闭包在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 ]
总结一下,就是
有可能会运行,也可能不会运行的代码,要使用闭包;
有可能会重复运行多次,也有可能一次也不运行的代码,要用闭包;