Что означает .delegate в Groovy?

Я нашел этот фрагмент кода:

def say = {println m}
say.delegate = [m:2]
say()

Это, по всей видимости, печатает 2. Как это работает? Где найти документацию по .delegate? Google привел меня на страницу преобразования делегата, на которой вообще не упоминается .delegate.


person ripper234    schedule 14.11.2011    source источник
comment
Однако на второй странице Google есть документация по нему: groovy.codehaus.org/ < / а>. Надеюсь это поможет.   -  person Esailija    schedule 14.11.2011
comment
mrhaki.blogspot.com/2009/11/   -  person tim_yates    schedule 14.11.2011


Ответы (2)


Делегат замыкания - это объект, который используется для разрешения ссылок, которые не могут быть разрешены в теле самого замыкания. Если бы ваш пример был написан так:

def say = {
  def m = 'hello'
  println m
}
say.delegate = [m:2]
say()

Он печатает "привет", потому что m может быть разрешено в закрытии. Однако, когда m не определен в закрытии,

def say = {
  println m
}
say.delegate = [m:2]
say()

delegate используется для разрешения ссылки, и в этом случае delegate - это Map, который отображает m в 2.

person Dónal    schedule 14.11.2011
comment
удобный способ указать для закрытия параметры по умолчанию: def say = { def m = m ?: 'hello'; println m } - person coderatchet; 09.01.2014
comment
@thenaglecode Я думаю, вы имели в виду это def say = { def m = it ?: 'hello'; println m } - person Dónal; 09.02.2015

Три свойства закрытия: this, владелец и делегат. Обычно делегат устанавливается на владельца.

def testClosure(closure) {
  closure()
}
testClosure() {
  println "this is " + this + ", super:" + this.getClass().superclass.name
  println "owner is " + owner + ", super:" + owner.getClass().superclass.name
  println "delegate is " + delegate + ", super:" + delegate.getClass().superclass.name

  testClosure() {
    println "this is " + this + ", super:" + this.getClass().superclass.name
    println "owner is " + owner + ", super:" + owner.getClass().superclass.name
    println "delegate is " + delegate + ", super:" + delegate.getClass().superclass.name
  }
}

отпечатки

this is ConsoleScript0@11d20d3, super:groovy.lang.Script
owner is ConsoleScript0@11d20d3, super:groovy.lang.Script
delegate is ConsoleScript0@11d20d3, super:groovy.lang.Script
this is ConsoleScript0@11d20d3, super:groovy.lang.Script
owner is ConsoleScript0$_run_closure1@caea19, super:groovy.lang.Closure
delegate is ConsoleScript0$_run_closure1@caea19, super:groovy.lang.Closure
person anish    schedule 14.11.2011
comment
По умолчанию может быть владельцем, но что движет Groovy DSL, так это то, что вы можете переназначить делегата любому объекту. - person Dónal; 10.02.2015