Groovy的Closure更象是一个“代码块”或者方法指针,代码在某处被定义然后在其后的调用处执行。 一个简单的示例:
def clos = { println "hello!" } println "Executing the closure:" clos() //prints "hello!"
注意上述示例中,”hello!”是在调用的时候被打印,而不是定义的时候! Closure还可以在其定义的作用域内,跟变量绑定,比如:
def localMethod() { def localVariable = new java.util.Date() return { println localVariable } } def clos = localMethod() println "Executing the closure:" clos() //prints the date when "localVariable" was defined
Closure的参数就是在”->“标识符之前的值,比如:
def clos = { a, b -> print a+b } clos( 5, 7 ) //prints "12"
”->“标识符是可选的,如果你的参数少于2个,那么它可以直接忽略掉。
在Closure中,有几个变量是有特殊意义的:
如果你的Closure只有一个参数,那你可以忽略此Closure参数的定义,如下所示:
def clos = { print it } clos( "hi there" ) //prints "hi there"
this : 跟Java一样,是定义Closure所在类的一个引用。
owner : 封闭的对象(是this或者含有Closure的Closure)
delegate :缺省值是owner,但是可以改变,比如在builder或者ExpandoMetaClass中可以修改其值。
请看示例:
class Class1 { def closure = { println this.class.name println delegate.class.name def nestedClos = { println owner.class.name } nestedClos() } } def clos = new Class1().closure clos.delegate = this clos() /* prints: Class1 Script1 Class1$_closure1 */
当一个方法的最后一个参数是Closure的时候,你可以定义一个内联(inline)的Closure,比如:
def list = ['a','b','c','d'] def newList = [] list.collect( newList ) { it.toUpperCase() } println newList // ["A", "B", "C", "D"]
在上述示例中,collect方法接受一个List和Closure参数,以下代码也可以达到同样的效果(不过看起来更繁琐):
def list = ['a','b','c','d'] def newList = [] def clos = { it.toUpperCase() } list.collect( newList, clos ) assert newList == ["A", "B", "C", "D"]
Groovy扩展了java.lang.Object的许多方法,使其可以接受Closure作为参数,更多可以看看GDK扩展Object中是如何使用Closure的。
更多参考: