什么是闭包
一个groovy闭包就像一个代码块或者方法指针,他是定义然后执行的一段代码,但是他有一些特性:隐含变量,支持自由变量,支持currying 。
我们先来看看一些例子:
1 | def clos = { println "hello!" } |
2 |
3 | println "Executing the Closure:" |
4 | clos() //prints "hello!" |
在上面的例子中”hello!”是因为调用clos()函数才打印出来的,而不是在定义的时候打印出来的。
参数
闭包的参数在->之前列出,比如:
1 | def printSum = { a, b -> print a+b } |
2 | printSum( 5 , 7 ) //prints "12" |
如果闭包的参数是少于2个的话,那么 ->是可以省略的。
Parameter notes
A Closure without -> , i.e. {} , is a Closure with one argument that is implicitly named as ‘it’. (see below for details) In some cases, you need to construct a Closure with zero arguments, e.g. using , defining etc. You have to explicity define your Closure as { -> } instead of just { }
You can also use varargs as parameters, refer to the for details. A JavaScript-style dynamic args could be simulated, refer to the .
自由变量
闭包能引用在参数列表中没有列出的变量,这些变量成为自由变量,他们的作用范围在他们定义的范围内:
1 | def myConst = 5 |
2 | def incByConst = { num -> num + myConst } |
3 | println incByConst( 10 ) // => 15 |
另外一个例子:
1 | def localMethod() { |
2 | def localVariable = new java.util.Date() |
3 | return { println localVariable } |
4 | } |
5 |
6 | def clos = localMethod() |
7 |
8 | println "Executing the Closure:" |
9 | clos() //prints the date when "localVariable" was defined |
隐式变量
it
如果你有一个闭包但是只有一个参数,那么你可以省略这个参数,比如:
1 | def clos = { print it } |
2 | clos( "hi there" ) //prints "hi there" |
this, owner, and delegate
this : 和java中是一样的, this
refers to the instance of the enclosing class where a Closure is defined
owner : the enclosing object (this
or a surrounding Closure)
delegate : by default the same as owner
, but changeable for example in a or
1 | class Class1 { |
2 | def closure = { |
3 | println this. class .name |
4 | println delegate. class .name |
5 | def nestedClos = { |
6 | println owner. class .name |
7 | } |
8 | nestedClos() |
9 | } |
10 | } |
11 |
12 | def clos = new Class1().closure |
13 | clos.delegate = this |
14 | clos() |
15 | /* prints: |
16 | Class1 |
17 | Script1 |
18 | Class1$_closure1 */ |
闭包作为方法参数
当一个方法使用闭包作为最后一个参数的话,那么就可以内嵌一个闭包,比如:
1 | def list = [ 'a' , 'b' , 'c' , 'd' ] |
2 | def newList = [] |
3 |
4 | list. collect ( newList ) { |
5 | it.toUpperCase() |
6 | } |
7 | println newList // ["A", "B", "C", "D"] |
在上面的collect方法中,他接受一个一个List和闭包,上面的代码等价于下面的代码:
1 | def list = [ 'a' , 'b' , 'c' , 'd' ] |
2 | def newList = [] |
3 |
4 | def clos = { it.toUpperCase() } |
5 | list. collect ( newList, clos ) |
6 |
7 | assert newList == [ "A" , "B" , "C" , "D" ] |
更多的信息:
Groovy继承了 java.lang.Object
并且许多的 Collection
和Map
的许多方法都接受闭包作为参数的 See for practical uses of Groovy's Closures.
See Also: