曾经很多Groovy开发者问我closure中的delegate是什么,有什么作用?
其实
closure中的delegate类似于类中的this,让我们看一个小例子,大家就清楚了 :)
class DelegateDemo {
String author = "山风小子"
def someMethod(closure) {
println "The original delegate of closure is: ${closure.delegate}"
closure.delegate = this
closure()
}
def greet(words) {
println words
}
}
def delegateDemo = new DelegateDemo()
delegateDemo.someMethod {
// 此处的delegate可以省略
delegate.greet("Hello, " + delegate.author)
}
delegateDemo.someMethod {
// 省略了delegate
greet("Hello, " + author)
}
运行结果:
The original delegate of closure is: Script16@13e6346
Hello, 山风小子
The original delegate of closure is: Script16@13e6346
Hello, 山风小子
注意:可能大家运行结果中的‘
Script16@13e6346’部分各不相同,但都是Script开始的一个类名(我这里的类名为Script16)
在类的实例方法中调用方法和引用属性时,我们可以省略方法或属性前this(比如this.method(),this.property可简写为method(),property),
表示调用或引用的是本实例的方法或属性。
类似地,在closure中调用方法和引用属性时,我们也可以省略方法和属性前的delegate,
表示调用或引用的是本closure的方法或属性(而closure通过delegate隐式变量将方法调用和变量引用‘委派’给了delegate引用的那个对象)
那closure的delegate的默认值是什么呢?默认值是closure所在context中的this(
为了方便理解起见,可以暂时这么记忆,因为closure套closure的情况不是很多见。其实closure的delegate的默认值是closure的隐式变量owner,而owner通常引用closure所在context中的this,除非closure所处的context又是个closure,那么owner引用的就是那个外层的closure,关于closure中的owner,我将在下篇文章《Groovy解惑——closure中的owner》中进行讲解),让我再用一个例子来说明一下吧:
class DelegateDemo {
String author = "山风小子"
def someMethod2(closure) {
println "The original delegate of closure is: ${closure.delegate}"
// 无需设置closure.delegate,因为closure的delegate默认值已经是DelegateDemo.this
//closure.delegate = this
closure()
}
def greet(words) {
println words
}
def test() {
def delegateDemo = new DelegateDemo()
// 传入someMethod2的closure {} 所处的context的this是DelegateDemo.this
// 所以closure的delegate的默认值也是DelegateDemo.this
delegateDemo.someMethod2 {
// 此处的delegate可以省略
delegate.greet("Hello, " + delegate.author)
}
delegateDemo.someMethod2 {
// 省略了delegate
greet("Hello, " + author)
}
}
}
def dd = new DelegateDemo()
dd.test()
运行结果:
The original delegate of closure is: DelegateDemo@1b5d2b2
Hello, 山风小子
The original delegate of closure is: DelegateDemo@1b5d2b2
Hello, 山风小子
注意DelegateDemo.this是Java中的表示方法,在Groovy并不支持,这么写是为了方便Java开发人员理解 :)
由于第一个例子中的closure所处的context中的this是Script16.this,类Script16是没有author属性和greet方法的,所以我们必须设置delegate
希望经过我这么一解释,大家对closure的delegate有所认识,清楚区分delegate和this :)
附:
朝花夕拾——Groovy & Grails
posted on 2007-12-22 15:50
山风小子 阅读(5358)
评论(1) 编辑 收藏 所属分类:
Groovy & Grails