Groovy 出身名门的闭包

让我们以闭包的简单定义开始,然后通过一个例子进一步阐述。一个闭包是被包装为一个对象的代码块,实际上闭包像一个可以接受参数并且能够有返回值的方法。

闭包是一个普 通对象,因为你能够通过一个变量引用到它,正如你能够引用到任何别的对象一样。

不要忘 记 JVM 根本就不知道你正在运行 groovy 代码,因此你能处理闭包对象也没有什么特别奇怪,闭包仅仅是一个对象,groovy 提供了一种非常容易创建闭包的方式和启用了一些非常常用的行为

如果把闭包与真实世界相联系的话,可以认为是一个信封和信封中的信纸,对于别的对 象来说,信纸上也许有“x=5,y=10”等等之内的变量值,对于一个闭包,信纸也许有一个操 作说明,你可以把这个信封给某个人,并且这个人也许按照信纸的指导来做工作;或者他们也将信封给别的人,它们也许根据不同的上下文按照信纸的指导做很许多次工作。

例如,信纸上的内容也许是:“把信送给你思念的人”,这个人也许开始找到他思念的人的地址,然后根据地址列表,一次接一次的按照信纸的说明做——联系在地址列表中的每一个人(每次一 个人)。

这个例子的等价的 groovy 代码应该是这样的:Closure envelope = { person -> new Letter(person).send() } addressBook.each (envelope)相当直观,并且符合 groovy 的语言习惯,这显示了闭包的差异(在这个例子中,闭包是变量 envelope)和闭包的用法(作为 each 方法的参数),当第一次看到闭包的时候,难以理解的部分是他们通常用在一个简短的块中间,groovy 使闭包非常简明,因为闭包使用非常频繁——但是简洁增加了学习难度,通过比较,先前的代码是使用 groovy 提供的方式编写的。当你看到这种方式的时候,它经常是如下所示的结构:addressBook.each { new Letter(it).send() }这仍旧是使用闭包作为单个参数的方法调用,但这是难以发现的——在 groovy 中传 递一个闭包给一个方法是非常平常,没有特殊规则。同样,如果闭包仅仅需要一个参数, groovy 提供了一个缺省的名称——it,因此,你不需要进行特别的声明,当我们使用 groovy 的简化操作的时候,我们的例子变得十分简短。

停下来并且想想为什么我们应该在第一个位置有闭包,始终记住:闭包是由一些代码组成的对象,并且 groovy 为闭包提供了简洁的语法。