以下示例改编自'Groovy in Action'
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
是指相同的范围?谢谢, 唐
答案 0 :(得分:10)
“this
”在块中意味着Groovy总是(无论是普通的类似Java的块还是Closure)周围的类(实例)。 “owner
”是Closure的一个属性,指向嵌入对象,它是一个类(实例),然后与“this
”相同,或者另一个Closure。我会完全忘记这部分的范围。因此,在上述情况下,这是正确的,“这个”指的是母亲。
现在让事情变得复杂......“这个”和Groovy中隐含的这一点并不相同。因此,如果您有一个关闭{foo()}
和{this.foo()}
,您可以得到不同的结果。 this.foo()
将始终解析为嵌入类,而只使用Groovy元对象协议(MOP)解析foo()
并且可以指向完全不同的东西。对于标准的Groovy构建器,构建器可以例如在该Closure上设置委托并捕获方法调用。无论如何......这就是为什么这部分被称为动态范围。
历史背景:
在Groovy 1.0之前,“this”是Closure对象本身。但是被更改了,因为如果构建器确实捕获了所有调用,实际上调用this.foo()
变得不可能。然后你无法再从构建器中调用本地方法。有很多尝试改变了标准的解决策略 - 以及大的情感讨论。但最后,将“this”改为引用嵌入类是解决问题的简单方法,更符合来自Java的人员,如果你坚持的话,你可以轻松绕过MOP。
答案 1 :(得分:9)
请参阅第144页
......这指的是关闭,而不是 声明的对象。在此刻, 关闭对我们起作用。他们 将所有方法调用委托给a 所谓的委托对象,由... 默认发生是声明 对象(即所有者)。这样做 封闭显示,如同所附 代码在生日上下文中运行。
对于你的问题;
从书中他们说“这指的是封闭,而不是宣告对象” 但是从bertport和我的实验来看,似乎“这个”实际上是宣告对象。这个闭包内部是否计算了调用闭包的范围?
无论哪种方式,你的问题答案仍然是“不”。
在上面显示的闭包内,这个和调用者指的是相同的范围?
我不敢。
请注意,Groovy in Action中的第143和144页需要进行一些更正
答案 2 :(得分:5)
{
def self = ({ owner })()
}
所有者:封闭对象(此对象或周围的Closure)。
答案 3 :(得分:1)
Sake说,“这个是闭包,而不是构造闭包的对象。”但是当我们运行这个脚本时,我们发现这个是一个母亲,而不是一个关闭。