我正在尝试比较 Smalltalk 中的两个字符串,但我似乎做错了什么。
我不断收到此错误:
未处理的异常:非布尔接收器。为真理而行。
stringOne := 'hello'.
stringTwo := 'hello'.
myNumber := 10.
[stringOne = stringTwo ] ifTrue:[
myNumber := 20].
知道我做错了什么吗?
我正在尝试比较 Smalltalk 中的两个字符串,但我似乎做错了什么。
我不断收到此错误:
未处理的异常:非布尔接收器。为真理而行。
stringOne := 'hello'.
stringTwo := 'hello'.
myNumber := 10.
[stringOne = stringTwo ] ifTrue:[
myNumber := 20].
知道我做错了什么吗?
尝试
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
正如其他人所说,如果您摆脱第一组方括号,它将按照您想要的方式工作。
但是为了更好地解释你遇到的问题:
[stringOne = stringTwo ] ifTrue:[myNumber := 20]
正在将消息传递ifTrue:
给一个块,而块不理解该方法,只有布尔对象可以。
如果您首先评估该块,它将评估为一个真正的对象,然后它将知道如何响应:
[stringOne = stringTwo] value ifTrue:[myNumber := 20]
或者正如其他人指出的那样,您真正应该做什么:
stringOne = stringTwo ifTrue:[myNumber := 20]
两者都在发送给它之前评估stringOne = stringTwo
为。true
ifTrue:[...]
[stringOne = stringTwo]
是一个块,而不是布尔值。当块被调用时,也许它会产生一个布尔值。但是您没有在这里调用该块。相反,您只是使块成为ifTrue
.
相反,请尝试:
(stringOne = stringTwo) ifTrue: [
myNumber := 20 ].
你应该阻止比较吗?我本来以为:
( stringOne = stringTwo ) ifTrue: [ myNumber := 20 ]
就足够了。
但我似乎做错了什么
鉴于您使用的是 VisualWorks,您的安装应该包括一个 doc 文件夹。
查看AppDevGuide.pdf - 它有很多关于使用 VisualWorks 编程的信息,甚至还有很多关于 Smalltalk 编程的介绍性信息。
查看开头的目录表,直到第 7 章“控制结构”,单击“分支”或“条件测试”,您将被带到 pdf 中的相应部分,该部分告诉您有关 Smalltalk if-then-else 的所有信息并给出可以帮助你了解你做错了什么的例子。
我想添加以下 50 美分:
由于块实际上是可以传递的 lambda,另一个很好的例子是以下方法:
do:aBlock ifCondition:aCondition
... some more code ...
aCondition value ifTrue: aBlock.
... some more code ...
aBlock value
...
所以 ifTrue:/ifFalse: 的参数实际上可以来自其他人。这种传入的条件通常在“..ifAbsent:”或“..onError:”类型的方法中很有用。
(最初的意思是评论,但我无法让代码示例未格式化)