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

时间:2022-06-13 22:48:07

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 (i.e. the scope in which julia is declared). Am I right in assuming that

根据这本书,封闭内部的这个值是最外层的范围(即宣布朱莉娅的范围)。我是否正确地承担这一点

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

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

Thanks, Don

4 个解决方案

#1


"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" refers to a mother.

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

And now to make things complicated... "this" and the implicit this are not the same in Groovy. So if you have a Closure {foo()} and {this.foo()} you can get differing results. 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. A builder may for example set a delegate on that Closure and catch the method invocation, for a Groovy builder that is standard. Anyway... that is why this part is called dynamic scoping.

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

Historic background: Before Groovy 1.0 "this" was the Closure object itself. But was changed because actually calling this.foo() became impossible if a builder did capture all calls. 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.

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

#2


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/8

#3


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

owner: the enclosing object (this or a surrounding Closure).

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

#4


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.

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

#1


"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" refers to a mother.

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

And now to make things complicated... "this" and the implicit this are not the same in Groovy. So if you have a Closure {foo()} and {this.foo()} you can get differing results. 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. A builder may for example set a delegate on that Closure and catch the method invocation, for a Groovy builder that is standard. Anyway... that is why this part is called dynamic scoping.

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

Historic background: Before Groovy 1.0 "this" was the Closure object itself. But was changed because actually calling this.foo() became impossible if a builder did capture all calls. 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.

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

#2


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/8

#3


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

owner: the enclosing object (this or a surrounding Closure).

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

#4


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.

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