groovy-闭包
什么是闭包
一个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 GString for templating, defining EMC Property etc. You have to explicity define your Closure as { -> } instead of just { }
You can also use varargs as parameters, refer to the Formal Guide for details. A JavaScript-style dynamic args could be simulated, refer to the Informal Guide.
自由变量
闭包能引用在参数列表中没有列出的变量,这些变量成为自由变量,他们的作用范围在他们定义的范围内:
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 builder or ExpandoMetaClass
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 GDK Extensions to Object for practical uses of Groovy's Closures.
See Also:
==============================================================================