一个Groovy闭包就像一个"代码块"或函数指针。它是一个代码片段的定义和执行。它拥有一些像隐含变量一样的特定属性,用来支持currying和和自由变量(后面我们会提到)。下面我们先忽略细节,看一下下面的简单例子。
def clos = { println "hello!" } println "Executing the Closure:" clos()
上述的闭包是在被调用的时候执行,而不是定义的时候。
闭包的参数位于->
标志前面,如下:
def printSum = { a, b -> print a+b } printSum( 5, 7 ) //prints "12"
->
标志是可选的,在参数少于2个的时候可以被省略。
一个像{}
的不包含->
标志的闭包其实是有一个隐含参数的,这个参数名是it
。在有些情况下你必须构造一个没有参数的闭包,比如使用GString模板,定义EMC属性等等,你必须用{ -> }
明确的定义你的闭包,而不是用{}
。
你当然也可以使用可变参数, 具体请参考正式指南。模拟javascript风格的动态参数,请参阅非正式指南。
闭包可以引用变量未列出的参数列表。这样的变量被称之为自由变量(Free Variables),他们被“绑定”在变量定义的范围之内:
def myConst = 5 def incByConst = { num -> num + myConst } println incByConst(10) // => 15
另外一个例子:
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
在groovy闭包当中,许多变量被定义成有特定的意义:
如果你有一个只含一个参数的闭包,你可能隐藏此参数,如下:
def clos = { print it } clos( "hi there" ) //prints "hi there"
this:在java中,this
指向闭包所定义的宿主类的实例。
owner:宿主对象(this
或附近的闭包)。
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 */
当一个方法把闭包当做最后一个参数时,你可以定义一个行内闭包,如下:
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
,许多集合
和Map
类的方法都支持闭包作为参数。在实际使用Groovy闭包的过程中请参阅GDK Extensions to Object。
参见: