Smalltalk 中的块可以自己运行吗?

Kev*_*gem 3 smalltalk

我知道可以通过这种方式传递和使用块。

但是有没有办法调用一个块,仅仅通过一个块?像这样的东西?

aBlock := [ ... ].
aBlock run.
Run Code Online (Sandbox Code Playgroud)

我尝试在系统浏览器中搜索 BlockClosure 类,但找不到它。

mel*_*des 6

是的!事实上,你可以用它们做一些非常有趣的事情,比如在它们内部激活它们。例如,此块以递归方式调用自身来计算阶乘:

factorialBlock := [:n | 
    n <= 1 
        ifTrue: [n]
        ifFalse: [n * (factorialBlock value: n - 1)]
]
Run Code Online (Sandbox Code Playgroud)

并尝试一下:

factorialBlock value: 5
Run Code Online (Sandbox Code Playgroud)

这不是一个很好的编码实践的例子,但它是块闭包的力量!


Lea*_*lia 5

让我们补充一下,此外value,如果你的块有参数,你还可以使用

[:f | <do something with f>] value: a
Run Code Online (Sandbox Code Playgroud)

其中f是一个形式参数(未绑定的变量名),a是一个将在发送时绑定的实际对象。f#value:

对于两个参数,使用value:value:and 对于很多valueWithArguments:,它接收一个Array


例子

[:x | x squared - 1] value: 3
                               ->  3 squared - 1 (i.e., 8)

[:x :y | x + 2 / (y - 4)] value: 2 value: 0
                               ->  2 + 2 / (0 - 4) (i.e., -1)
Run Code Online (Sandbox Code Playgroud)

锻炼

评估以下内容的结果是什么?:

block := [:x | x value: 2].
block value: [:y | y + 1]
Run Code Online (Sandbox Code Playgroud)