简体   繁体   English

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

[英]Groovy: meaning of 'this' inside a closure

The following example is adapted from 'Groovy in Action' 以下示例改编自'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 

According to the book, the value of this inside the closure is the outermost scope (ie the scope in which julia is declared). 根据这本书,封闭内部的this值是最外层的范围(即宣布julia的范围)。 Am I right in assuming that 我是否正确地假设

  • this inside a closure evaluates to the scope in which the closure is called? 闭包内部的this值是否为调用闭包的范围?
  • within the closure shown above, this and caller refer to the same scope? 在上面显示的闭包内, thiscaller指的是相同的范围?

Thanks, Don 谢谢,唐

" this " in a block mean in Groovy always (be it a normal Java-like block or a Closure) the surrounding class (instance). 块中的“ this ”意味着Groovy总是(无论是普通的类似Java的块还是Closure)周围的类(实例)。 " 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. owner ”是Closure的一个属性,指向嵌入对象,它是一个类(实例),然后与“ this ”相同,或者另一个Closure。 I would forget about the scope thing totally for this part. 我会完全忘记这部分的范围。 So in the case above it is correct, that "this" refers to a mother. 因此,在上述情况下,这是正确的,“这个”指的是母亲。

And now to make things complicated... "this" and the implicit this are not the same in Groovy. 现在让事情变得复杂......“这个”和Groovy中隐含的这一点并不相同。 So if you have a Closure {foo()} and {this.foo()} you can get differing results. 因此,如果你有一个Closure {foo()}{this.foo()}你可以得到不同的结果。 this.foo() will always be resolved to the embedding class, while only foo() will be resolved using the Groovy meta object protocol (MOP) and can point to something entirely different. this.foo()将始终解析为嵌入类,而只使用Groovy元对象协议(MOP)解析foo() )并指向完全不同的东西。 A builder may for example set a delegate on that Closure and catch the method invocation, for a Groovy builder that is standard. 对于标准的Groovy构建器,构建器可以例如在该Closure上设置委托并捕获方法调用。 Anyway... that is why this part is called dynamic scoping. 无论如何......这就是为什么这部分被称为动态范围。

Historic background: Before Groovy 1.0 "this" was the Closure object itself. 历史背景:在Groovy 1.0之前“this”是Closure对象本身。 But was changed because actually calling this.foo() became impossible if a builder did capture all calls. 但是被改变了,因为实际上调用this.foo()变得不可能,如果构建器确实捕获了所有调用。 then you had no way to call local methods from within the builder anymore. 然后你无法再从构建器中调用本地方法。 There was a lot of tries with changing the standard resolve strategy - and big emotional discussions too. 有很多尝试改变了标准的解决策略 - 以及大的情感讨论。 But in the end, changing "this" to refer to the embedding class was a simple solution to the problem and is more in line with people coming from Java plus it let's you easily bypass the MOP if you insist. 但最后,将“this”更改为引用嵌入类是解决问题的简单方法,更符合来自Java的人员,如果你坚持的话,你可以轻松绕过MOP。

Take a look at page 144 看一下第144页

...this refers to the closure, not to the declaring object. ......这是指关闭,而不是声明对象。 At this point, closures play a trick for us. 在这一点上,闭包对我们来说是个窍门。 They delegate all method calls to a so-called delegate object, which by default happends to be the declaring object (that is, the owner). 他们将所有方法调用委托给一个所谓的委托对象,默认情况下,委托对象就是声明对象(即所有者)。 This make the closure appear as if the enclosed code runs in the birthday context . 这使得闭包看起来就像封闭的代码在生日上下文中运行一样。

For your questions; 对于你的问题;

this inside a closure evaluates to the scope in which the closure is called? 闭包内部的这个值是否为调用闭包的范围?

from the book they state that "this refer to the closure, not to the declaring object" But from bertport and my experiment, it seems "this" is actually the declaring object. 从书中他们说“这指的是封闭,而不是宣告对象”但是从bertport和我的实验来看,似乎“这”实际上是宣告对象。

Either ways, the answer is still "no" for your question. 无论哪种方式,你的问题的答案仍然是“不”。

within the closure shown above, this and caller refer to the same scope? 在上面显示的闭包内,这和调用者指的是相同的范围?

I'm afraid not. 恐怕不是。

Be aware that page 143 and 144 in Groovy in Action need some corrections 请注意,Groovy in Action中的第143和144页需要进行一些更正

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

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

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

owner: the enclosing object (this or a surrounding Closure ). 所有者:封闭对象(此对象或周围的Closure )。

Sake says, " this is the closure not the object where the closure [is] constructed." 萨克说,“ 关闭而不是封闭[构建]的对象。” But when we run this script, we find that this is a Mother, not a Closure. 但是当我们运行这个脚本时,我们发现是一个母亲,而不是一个关闭。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM