9

我正在尝试比较 Smalltalk 中的两个字符串,但我似乎做错了什么。

我不断收到此错误:

未处理的异常:非布尔接收器。为真理而行。

stringOne := 'hello'.
stringTwo := 'hello'.
myNumber := 10.

[stringOne = stringTwo ] ifTrue:[
   myNumber := 20].

知道我做错了什么吗?

4

6 回答 6

17

尝试

stringOne = stringTwo 
     ifTrue: [myNumber := 20]`

我认为您不需要在第一行使用方括号

找到了很好的解释。整件事都在这里

在 Smalltalk 中,布尔值(即 True 或 False)是对象:具体来说,它们是抽象基类 Boolean 的实例化,或者更确切地说是它的两个子类 True 和 False。所以每个布尔值都有 True 或 False 类型,并且没有实际的成员数据。Bool 有两个虚函数 ifTrue: 和 ifFalse:,它们将代码块作为参数。True 和 False 都覆盖了这些函数;True 的 ifTrue 版本:调用它传递的代码,而 False 的版本什么也不做(ifFalse 反之亦然:)。这是一个例子:

a < b
  ifTrue: [^'a is less than b']
  ifFalse: [^'a is greater than or equal to b']

顺便说一句,方括号中的那些东西本质上是匿名函数。除了它们是对象,因为在 Smalltalk 中一切都是对象。现在,发生的事情是我们用参数 b 调用 a 的 "<" 方法;这将返回一个布尔值。我们调用它的 ifTrue: 和 ifFalse: 方法,将我们想要在任何一种情况下执行的代码作为参数传递。效果和Ruby代码一样

if a < b then
  puts "a is less than b"
else
  puts "a is greater than or equal to b"
end
于 2009-10-29T02:35:34.037 回答
5

正如其他人所说,如果您摆脱第一组方括号,它将按照您想要的方式工作。

但是为了更好地解释你遇到的问题:

[stringOne = stringTwo ] ifTrue:[myNumber := 20]

正在将消息传递ifTrue:给一个块,而块不理解该方法,只有布尔对象可以。

如果您首先评估该块,它将评估为一个真正的对象,然后它将知道如何响应:

[stringOne = stringTwo] value ifTrue:[myNumber := 20]

或者正如其他人指出的那样,您真正应该做什么:

stringOne = stringTwo ifTrue:[myNumber := 20]

两者都在发送给它之前评估stringOne = stringTwo为。trueifTrue:[...]

于 2009-10-29T03:03:28.067 回答
1

[stringOne = stringTwo]是一个块,而不是布尔值。当块被调用时,也许它会产生一个布尔值。但是您没有在这里调用该块。相反,您只是使块成为ifTrue.

相反,请尝试:

(stringOne = stringTwo) ifTrue: [
    myNumber := 20 ].
于 2009-10-29T02:37:22.457 回答
0

你应该阻止比较吗?我本来以为:

( stringOne = stringTwo ) ifTrue: [ myNumber := 20 ]

就足够了。

于 2009-10-29T02:36:05.873 回答
0

但我似乎做错了什么

鉴于您使用的是 VisualWorks,您的安装应该包括一个 doc 文件夹

查看AppDevGuide.pdf - 它有很多关于使用 VisualWorks 编程的信息,甚至还有很多关于 Smalltalk 编程的介绍性信息。

查看开头的目录表,直到第 7 章“控制结构”,单击“分支”或“条件测试”,您将被带到 pdf 中的相应部分,该部分告诉您有关 Smalltalk if-then-else 的所有信息并给出可以帮助你了解你做错了什么的例子。

于 2009-10-30T18:02:17.243 回答
0

我想添加以下 50 美分:

由于块实际上是可以传递的 lambda,另一个很好的例子是以下方法:

do:aBlock ifCondition:aCondition
    ... some more code ...
    aCondition value ifTrue: aBlock.
    ... some more code ...
    aBlock value
    ...

所以 ifTrue:/ifFalse: 的参数实际上可以来自其他人。这种传入的条件通常在“..ifAbsent:”或“..onError:”类型的方法中很有用。

(最初的意思是评论,但我无法让代码示例未格式化)

于 2011-05-11T07:55:46.810 回答