技术开发 频道

Groovy解惑——closure中的delegate

  【IT168 技术文档】曾经很多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 :)

0
相关文章