Pharo中的闭包(块 | 匿名函数)

标签: pharo ; smalltalk ;


闭包在Pharo中被称为“块”,相当于其它语言中的匿名方法或者是词法闭包。将表达式放在方括号中就构成了一个词法闭包。这里要强调,所谓的词法闭包,本质上就是一个携带着环境的匿名函数。如果在函数内部引用了外部环境中的变量,则外部变量的值也被封闭在一起,在求值时不受外部环境的影响,这就是闭包的概念。

最简单的闭包:

[ doSomething ]

闭包是一个对象,除非给它发送value消息,不然它内部的表达式是不求值的。

[ a block ] value

给一个闭包发送value消息,相当于调用这个匿名函数,函数开始运行。

闭包可以定义局部变量,需要用两个竖线包起来

[ | local variables | body ]

函数可以有参数,参数与函数体之间用竖线隔开:

[ :i | 
  | local variables | 
  body ]

对于需要参数的匿名函数,需要用value:消息去调用,并且传递合适的参数

[ :i | body ] value: arg

value:传递的参数是位置参数,最多可以有四个

[ :i :j :k :l | body ] value: arg1 value: arg2 value: arg3 value: arg4

函数中可以有多个表达式,总是隐式地返回最后一个表达式的值,不需要显式的return(^)。说实话,什么时候需要return,什么时候不需要return, 反正我现在还没搞明白。

BTW:Smalltalk 的语法规则是很简单的,透着极致的简约美感。但是真的要使用这些简单的规则,却需要比较高的心智成本。

闭包在Pharo中应用得相当广泛。

用在分支判断中:

aBoolean 
  ifTrue: [ aBlock ]
  ifFalse: [ aBlock ]
  

用在逻辑表达式中:

aBoolean and: [ aBoolean ]
aBoolean or: [ aBoolean ]

用在迭代中作为参数传递:

5 timesRepeat: [ aBlock ]

总结一下,就是

  1. 有可能会运行,也可能不会运行的代码,要使用闭包;

  2. 有可能会重复运行多次,也有可能一次也不运行的代码,要用闭包;