我正在尝试比较Smalltalk中的两个字符串,但我似乎做错了。
我一直收到这个错误:
未处理的异常:非布尔接收器。继续求真。
stringOne := 'hello'.
stringTwo := 'hello'.
myNumber := 10.
[stringOne = stringTwo ] ifTrue:[
myNumber := 20].
知道我做错了吗?
答案 0 :(得分:16)
尝试
stringOne = stringTwo
ifTrue: [myNumber := 20]`
我不认为你在第一行需要方括号
找到了很好的解释。整个thing is here
在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中的一个对象。现在,正在发生的事情是我们称之为“&lt;”方法,带参数b;这会返回一个布尔值。我们调用它的ifTrue:和ifFalse:方法,作为参数传递我们想要在任何一种情况下执行的代码。效果与Ruby代码的效果相同
if a < b then
puts "a is less than b"
else
puts "a is greater than or equal to b"
end
答案 1 :(得分:4)
正如其他人所说,如果你摆脱第一组方括号,它会以你想要的方式工作。
但是要解释你遇到的问题更好:
[stringOne = stringTwo ] ifTrue:[myNumber := 20]
将消息ifTrue:
传递给一个块,并且块不理解该方法,只有布尔对象才能理解。
如果您首先评估该块,它将评估为一个真实的对象,然后该对象将知道如何响应:
[stringOne = stringTwo] value ifTrue:[myNumber := 20]
或者你应该做什么,正如其他人指出的那样:
stringOne = stringTwo ifTrue:[myNumber := 20]
在向stringOne = stringTwo
发送true
之前评估ifTrue:[...]
至{{1}}。
答案 2 :(得分:1)
[stringOne = stringTwo]
是一个块,而不是布尔值。调用块时,可能会产生布尔值。但你不是在这里调用块。相反,您只是使该块成为ifTrue
的接收者。
相反,请尝试:
(stringOne = stringTwo) ifTrue: [
myNumber := 20 ].
答案 3 :(得分:0)
你应该阻止比较吗?我原以为:
( stringOne = stringTwo ) ifTrue: [ myNumber := 20 ]
就够了。
答案 4 :(得分:0)
但我似乎做错了什么
鉴于您使用的是VisualWorks,您的安装应包含文件夹。
查看 AppDevGuide.pdf - 它有很多关于使用VisualWorks进行编程的信息,还有更多关于Smalltalk编程的介绍性信息。
查看开头的内容表,直到第7章“控制结构”,单击“分支”或“条件测试”,您将进入pdf中相应的部分。告诉你关于Smalltalk if-then-else的所有内容,并举出一些例子来帮助你了解你做错了什么。
答案 5 :(得分:0)
我想添加以下50Cent:
因为块实际上是lambdas可以传递,另一个很好的例子是以下方法:
do:aBlock ifCondition:aCondition
... some more code ...
aCondition value ifTrue: aBlock.
... some more code ...
aBlock value
...
所以ifTrue:/ ifFalse:的参数实际上可能来自其他人。这种传入条件在“..ifAbsent:”或“..onError:”类方法中通常很有用。
(最初的意思是评论,但我无法获得未格式化的代码示例)