Groovy: значение 'this' внутри замыкания
Следующий пример адаптирован из "Groovy в действии"
class Mother {
Closure birth() {
def closure = { caller ->
[this, caller]
}
return closure
}
}
Mother julia = new Mother()
closure = julia.birth()
context = closure.call(this)
println context[0].class.name // Will print the name of the Script class
assert context[1] instanceof Script
Согласно книге, значение this
внутри замыкания является самой внешней областью (т.е. область, в которой объявляется julia
). Правильно ли я полагаю, что
-
this
внутри замыкания оценивается область, в которой называется замыкание?
- в приведенном выше закрытии,
this
и caller
относятся к той же области видимости?
Спасибо,
Дон
Ответы
Ответ 1
Взгляните на страницу 144
... это относится к закрытию, а не к объявляющий объект. С этой точки зрения, замыкания для нас играют. Oни делегировать все вызовы методов на так называемый объект делегирования, который по умолчанию считается объявлением объект (то есть владелец). Это делает закрытие выглядит , как если бы прилагаемый код запускается в контексте дня рождения.
За ваши вопросы;
это внутри замыкания оценивается в области, в которой называется замыкание?
из книги они заявляют, что "это относится к закрытию, а не к объявляющему объекту"
Но из bertport и моего эксперимента кажется, что "this" фактически является объявляющим объектом.
В любом случае ответ по-прежнему "нет" для вашего вопроса.
в закрытии, показанном выше, это и вызывающий абонент ссылаются на ту же область?
Я боюсь, что нет.
Помните, что на стр. 143 и 144 в Groovy в Action необходимо внести некоторые исправления
http://groovy.canoo.com/errata/erratum/show/5
http://groovy.canoo.com/errata/erratum/show/8
Ответ 2
"this
" в значении блока в Groovy всегда (будь то обычный Java-подобный блок или закрытие) окружающего класса (экземпляра). "owner
" является свойством Closure и указывает на объект внедрения, который является либо классом (экземпляром), а затем тогда же как "this
" или другим закрытием. Я бы забыл об этой предметной области полностью для этой части. Поэтому в приведенном выше правиле правильно, что "this" относится к матери.
И теперь, чтобы усложнить ситуацию... "this", и это неявно, это не то же самое в Groovy. Поэтому, если у вас есть Closure {foo()}
и {this.foo()}
, вы можете получить разные результаты. this.foo()
всегда будет разрешен для класса внедрения, а только foo()
будет разрешен с использованием протокола метаданных Groovy (MOP) и может указывать на нечто совершенно другое. Строитель может, например, установить делегат в этом Closure и уловить вызов метода для стандартного конструктора Groovy. В любом случае... поэтому эта часть называется динамическим охватом.
Исторический фон:
До Groovy 1.0 "this" был сам объект Closure. Но было изменено, потому что фактически вызов this.foo()
стал невозможным, если строитель выполнил захват всех вызовов. то у вас не было способа больше называть локальные методы изнутри строителя. Было много попыток изменить стандартную стратегию решения - и большие эмоциональные дискуссии тоже. Но в конце концов, изменение "this" для ссылки на класс внедрения было простым решением проблемы и в большей степени соответствовало людям, приходящим из Java, и это позволяло вам легко обойти СС, если вы настаиваете.
Ответ 3
{
def self = ({ owner })()
}
owner: прилагаемый объект (этот или окружающий Closure).
Ответ 4
Саке говорит: "это закрытие, а не объект, где построено замыкание". Но когда мы запускаем этот script, мы обнаруживаем, что это Мать, а не Закрытие.