什么是闭包(Groovy)
-
博客分类:
- Grails & Groovy
GroovyJavaCC++C#
Groovy的闭包就像一个代码段或者说方法指针。它是一段被定义并在稍后的时点上运行的代码。
Simple Example
- defclos={println"hello!}
def clos = { println "hello! }
- 示例:defclos={println"hello!}
- println"Executingtheclosure:"
- clos()
示例: def clos = { println "hello!} println "Executing the closure:" clos()
注意在上面的例子中,"hello"在闭包被调用的时候才打印出来,而不是在定义的时候。
Closures may be "bound" to variables within the scope where they are defined:
闭包可以与在特定范围内定义的变量绑定起来(这句不知翻译的对错,请看原文)
- deflocalMethod(){
- deflocalVariable=newjava.util.Date()
- return{printlnlocalVariable}
- }
- defclos=localMethod()
- println"Executingtheclosure:"
- clos()//打印出当localVariables被创建时的时间
def localMethod() { def localVariable = new java.util.Date() return { println localVariable } } def clos = localMethod() println "Executing the closure:" clos() //打印出当localVariables被创建时的时间
参数:
闭包的参数在->之前被列出,比如
- defclos={a,b->printa+b}
- clos(5,7)//prints"12"
def clos = { a, b -> print a+b } clos( 5, 7 ) //prints "12"
-> 这个符号是可选的,当你定义的闭包的参数小于两个时就可将其省略
隐含的变量
在闭包中,有几个变量有着特别的含义
it(注意是小写):
如果你的闭包定义仅含有一个参数,可以将其省略,Groovy自动用it来代替
比如:
- defclos={printit}
- clos("hithere")//prints"hithere"
def clos = { print it } clos( "hi there" ) //prints "hi there"
this, owner, 和 delegate
this : 如同在Java中一样,this 代表闭包被定义的类
owner : 包含闭包的对象,有可能是定义闭包的类或者是另外一个闭包
delegate : 默认与owner相同,but changeable for example in a builder or ExpandoMetaClass
- Example:
- classClass1{
- defclosure={
- printlnthis.class.name
- printlndelegate.class.name
- defnestedClos={
- printlnowner.class.name
- }
- nestedClos()
- }
- }
- defclos=newClass1().closure
- clos.delegate=this
- clos()
- /*prints:
- Class1
- Script1
- Class1$_closure1*/
Example: 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 */
作为方法参数的闭包
当一个方法的最后一个参数是闭包的时候,我们可以将闭包紧随其后定义,如
- deflist=['a','b','c','d']
- defnewList=[]
- list.collect(newList){
- it.toUpperCase()
- }
- printlnnewList//["A","B","C","D"]
def list = ['a','b','c','d'] def newList = [] list.collect( newList ) { it.toUpperCase() } println newList // ["A", "B", "C", "D"]
上一个例子也可以用下面的方法实现,就是稍显冗长。
- deflist=['a','b','c','d']
- defnewList=[]
- defclos={it.toUpperCase()}
- list.collect(newList,clos)
- assertnewList==["A","B","C","D"]
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
上文提到的 collect 就是这样一个例子
collect(Collection collection) {closure} 返回一个集合,并将该集合的每一项添加到给定的集合中