首页 文章

Groovy:闭包内'this'的含义

提问于
浏览
10

以下示例改编自'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 回答

  • 10

    this " in a block mean in Groovy always (be it a normal Java-like block or a Closure) the surrounding class (instance). " owner " is a property of the Closure and points to the embedding object, which is either a class (instance), and then then same as " this ", or another Closure. I would forget about the scope thing totally for this part. So in the case above it is correct, that "这”指的是一位母亲 .

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

    历史背景:在Groovy 1.0之前"this"是Closure对象本身 . 但是被改变了,因为如果建造者确实捕获了所有呼叫,实际上调用 this.foo() 变得不可能 . 然后你无法再从构建器中调用本地方法 . 有很多尝试改变了标准的解决策略 - 以及大的情感讨论 . 但最后,更改"this"以引用嵌入类是解决问题的简单方法,并且更符合来自Java的人员,如果你坚持的话,你可以轻松绕过MOP .

  • 5

    看一下第144页

    ......这是指关闭,而不是声明对象 . 在这一点上,闭包对我们来说是个窍门 . 他们将所有方法调用委托给一个所谓的委托对象,默认情况下,委托对象就是声明对象(即所有者) . 这使得闭包看起来就像封闭的代码在生日上下文中运行一样 .

    对于你的问题;

    这个闭包内部是否计算了调用闭包的范围?

    从书中他们说“这指的是封闭,而不是宣告对象”但是从bertport和我的实验来看,似乎“这”实际上是宣告对象 .

    无论哪种方式,你的问题的答案仍然是“不” .

    在上面显示的闭包内,这和调用者指的是相同的范围?

    恐怕不是 .

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

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

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

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

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

  • 9

    萨克说,“这是 closure ,而不是封闭[构建]的对象 . ”但是当我们运行这个脚本时,我们发现这是一个母亲,而不是一个关闭 .

相关问题