Groovy:封闭内部'this'的含义

时间:2009-05-04 13:26:05

标签: groovy closures

以下示例改编自'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计算闭包被调用的范围?
  • 在上面显示的闭包内,thiscaller是指相同的范围?

谢谢, 唐

4 个答案:

答案 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页需要进行一些更正

http://groovy.canoo.com/errata/erratum/show/5

http://groovy.canoo.com/errata/erratum/show/8

答案 2 :(得分:5)

{
    def self = ({ owner })()
}

所有者:封闭对象(此对象或周围的Closure)。

答案 3 :(得分:1)

Sake说,“这个闭包,而不是构造闭包的对象。”但是当我们运行这个脚本时,我们发现这个是一个母亲,而不是一个关闭。