Smalltalk:“&”和“and:”有什么区别

Sol*_*Sol 12 smalltalk pharo

我刚在大学开始学习 Smalltalk。

我想知道消息&和之间的区别and:(就像|or:

Jam*_*ter 15

欢迎来到小聊!您问了一个很好的问题,指出了块外部或内部表达式的一些细微差别。

'&' 消息是一种“二进制”消息,因此仅采用一个参数。在这种情况下,参数应为布尔值或计算结果为布尔值的表达式。最重要的是,对于我们在此比较中的目的,表达式将始终被求值。

“and:”消息是一个“关键字”消息,也只接受一个参数。但在这种情况下,参数预计是一个块,如果稍后发送“值”消息将返回布尔值。因此,出于我们比较的目的,块并不总是被评估。(二进制消息和关键字消息之间的差异对于这个问题并不重要。)

不评估参数的选项允许短路评估,其中了解左侧通常可以让我们避免(可能昂贵的)右侧计算。因此,如果左侧(“接收者”)为假,则评估右侧就不会获得任何结果。

因此,请考虑以下事项:

self cheapFalse & self expensiveTrue. "an expensive way to get false"
self cheapFalse and: [self expensiveTrue]. "a cheap way to get false"
Run Code Online (Sandbox Code Playgroud)


Uko*_*Uko 9

一个明显的区别是,这and:是一条关键字消息,因此您可以编写类似的内容

a > b and: [b < c]
Run Code Online (Sandbox Code Playgroud)

while with&你需要在这个表达式中使用括号:

a > b & (b < c)
Run Code Online (Sandbox Code Playgroud)

因为所有二进制消息 ( +, -, >, <, &, |) 具有相同的优先级。

更重要的是and:期望or:块同时&期望值|。这意味着你可以写

this shouldRedraw and: [ obj stateChanged ]
Run Code Online (Sandbox Code Playgroud)

obj stateChanged仅当为 true 时才会执行where this shouldRedraw。如果您想优化代码并避免计算当前不需要的内容,这非常有用。

  • 您应该将“b &lt; c”放在第一个代码示例中的块中。另外,“shouldCompute”应更改为“shouldRedraw”。 (2认同)
  • 请注意,没有什么可以阻止将块传递给语言中的二进制消息(如果您愿意,您可以创建需要块参数的二进制消息)。这只是内核库中使用的约定。 (2认同)