【问题标题】:Groovy: meaning of 'this' inside a closureGroovy:闭包内“this”的含义
【发布时间】:2010-10-23 15:13:56
【问题描述】:

以下示例改编自“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 指的是同一个范围?

谢谢, 唐

【问题讨论】:

    标签: groovy closures


    【解决方案1】:

    "this" 在 Groovy 中的块中总是意味着周围的类(实例)(无论是普通的类似 Java 的块还是闭包)。 “owner”是闭包的一个属性,指向嵌入对象,或者是一个类(实例),然后和“this”一样,或者另一个闭包。我会完全忘记这部分的范围。所以在上面的例子中,“this”指的是一位母亲是正确的。

    现在让事情变得复杂......“this”和隐含的 this 在 Groovy 中是不一样的。所以如果你有一个闭包{foo()}{this.foo()} 你会得到不同的结果。 this.foo() 将始终解析为嵌入类,而只有 foo() 将使用 Groovy 元对象协议 (MOP) 解析,并且可以指向完全不同的东西。例如,对于标准的 Groovy 构建器,构建器可以在该闭包上设置委托并捕获方法调用。无论如何...这就是为什么这部分被称为动态范围。

    历史背景: 在 Groovy 1.0 之前,“this”是 Closure 对象本身。但是已更改,因为如果构建器确实捕获了所有调用,则实际上调用 this.foo() 变得不可能。那么您将无法再从构建器中调用本地方法。有很多尝试改变标准的解决策略——也有很多情绪化的讨论。但最后,将“this”更改为引用嵌入类是解决问题的一个简单方法,并且更符合来自 Java 的人,而且如果您坚持,它可以让您轻松绕过 MOP。

    【讨论】:

    • 感谢@blackdrag 的解释!那么我是否正确地说,在执行闭包时,不可能获得对闭包本身的引用?
    • ´def cl; cl = {返回 cl}; assert cl() == cl´ 展示了如何获取要在块内使用的引用。但这是正确的,不使用外部上下文就不可能获得对闭包的引用。
    【解决方案2】:

    看看第 144 页

    ...this 指的是闭包,而不是 声明对象。在此刻, 闭包对我们来说是个把戏。他们 将所有方法调用委托给一个 所谓的委托对象,由 默认情况下是声明 对象(即所有者)。这使 闭包出现好像封闭 代码在生日上下文中运行。

    对于您的问题;

    闭包内的this计算出调用闭包的作用域?

    从书中他们说“this 指的是闭包,而不是声明的对象” 但从 bertport 和我的实验来看,似乎“this”实际上是声明对象。

    无论哪种方式,您的问题的答案仍然是“否”。

    在上面显示的闭包中,this 和 caller 是指同一个作用域吗?

    恐怕不会。

    请注意,Groovy in Action 中的第 143 页和第 144 页需要一些更正

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

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

    【讨论】:

      【解决方案3】:
      {
          def self = ({ owner })()
      }
      

      owner:封闭对象(this 或周围的Closure)。

      【讨论】:

        【解决方案4】:

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

        【讨论】:

        • 是的。你是对的 context[0] 确实是母亲(朱莉娅)。这本书没有正确解释。
        猜你喜欢
        • 2011-04-22
        • 1970-01-01
        • 2017-04-12
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多