Groovy 闭包范围

别的范围的元素也可以像本地变量一样被访问是不令人感到意外的:this 的值,属性、方法和参数。

这通常都是正确的,但是 this 引用时有个特例,在闭包中,你正确的猜想 this 将引用到当前对象,这是闭包对象本身,在另一方面,使用 this.reference 和直接使用 reference 来处理本地引用是没有区别的。

通过一个名称为 ow ner 的变量可以获取到声明闭包的对象,列表 5.8 延展了最初例子的目的,显示了其余范围的元素。

我们实现一个类 Mother,这个类通过 birth 的方法来获取到一个闭包,这个类有一个字段,另外的一个方法,参数列表和本地变量,这个闭包返回这些在当前上下文(或者范围)所有元素的列表,在后台,这些元素在声明的时候被绑定而不是在闭包被调用的时候,让我们来看看调用的结果吧。

在(1)我们在方法声明的时候增加了返回类型,指明这个方法将返回一个闭包对象,

一个返回闭包的方法通常不是闭包的用法,但是有时候这是方便的,注意在这个方法中我们是在声明期间,闭包的列表将被返回,但是闭包仍然没有调用。

在构建了一个新的 Mother 实例之后,我们在(2)调用它的 b irth 方法用来接收一个新的闭包对象,到现在,闭包还没有被调用,元素列表仍然还没有被构建。

在(3),我们显式调用闭包,闭包从它出生的地方构建元素列表,我们将列表保存在一个变量中供后面查阅,注意我们把自身作为参数传递给闭包,这样可以在闭包中作为 caller使用。

在(4)输出了这次运行的时候的脚本类的名称,groovy 1.0 之前的版本打印的是闭包类型。

实例变量 field ,foo()调用的结果,本地变量 local,参数 param,这些所有的都有期望的值,在(5)证明了这个结果,当执行闭包的时候它们不知道 Script,这是我们预期的重新 调用,只有 foo()有点复杂,它总是 this.foo()的缩写,正如我们前面说的那样,this 引用到闭 包,而不是声明闭包的对象,在这里,闭包有点糊弄人,它们将所有的方法调用代理给 delegate 对象,delegate 缺省是声明闭包的对象(也就是 ow ner),这样保证了闭包在它的上下文中运行。

显式传递给闭包的 caller 参数确保了在闭包中可以进行访问,在(6)显示了用法,在这本书中前面的所有的闭包的例子中,调用闭包的对象和声明闭包的对象都是相同的,因此,我们可以容易的使用,你也许注意到了调用者对象都是声明对象,如果这样让你感觉很疯狂, 不要担心,概念也许稍微有点不熟悉,从 times 例子重新开始,如果你想这样做,不算太晚。

在闭包中,魔术变量 ow ner 引用到声明闭包的对象,如(7)所示。

如(8)每次调用 birth 方法的时候,闭包都重新构建,对于闭包来说,闭包的花括号就 像 new 关键字一样,这后面是闭包和方法的根本差别,方法在类产生的时候就被构建,而且只会构建一次,闭包对象在运行的时候被构建,并且相同的代码也有可能被构建多次。 图 5.4 显示了列表 5.8 的引用关系。

关于闭包的语法来自如 Lisp、smalltalk、per l、ruby 和 python 等语言。

图 5.4 列表 5.8 的例子中对象引用关系图

我们的目的是适当的介绍 groovy 的闭包,这有助你在网上寻找更复杂的例子的时候给 你基本的理解,而不是给出一个蓄意费解的例子,无论如何,我们提供一个关于闭包范围的例子,以使别的复杂的任务简单易懂。