Groovy闭包的业主

时间:2016-03-28 10:41:53

标签: java groovy closures

根据“Groovy in Action”,可以通过多种方式声明闭包。有两种方法: def printer = {line - > println line} def闭包getPrinter(){     return {line - > println line} }

根据关闭中的Closures, official documentation owner

  

“返回直接封闭对象,无论是闭包还是类。”

好的,我们来看看:

class Mother {
    def prop = 'prop'
    def method(){ 'method' }
    Closure birth (param) {
        def local = 'local'
        def closure1 = {
            [ this, prop, method(), local, param ]
        }
        return closure1
    }

    def birth2 = { param ->
        def local = 'local'
        def closure2 = {
            [ this, prop, method(), local, param ]
        }
        return closure2
    }
}
Mother julia = new Mother()
def closure = julia.birth('param')
assert closure.owner == julia
assert closure.delegate == julia

def closure2 = julia.birth2('param')
assert closure2.owner == julia  
assert closure2.delegate == julia

在这两种情况下,根据文档,birth anb birth2都是关闭。在这些闭包中,我们声明了closure1closure2。我给他们的名字只是为了引用它们。这些closure1closure2的所有者应引用birthbirth2。根据官方文件。但在第一个示例中,owner引用了类的实例 - julia。在第二个例子中,我认为它指的是birth2,但不知道如何断言它。

有人可以解释这个区别吗?

2 个答案:

答案 0 :(得分:0)

birth是一个方法,而不是闭包

birth2是一个闭包

存在差异

答案 1 :(得分:0)

您已经了解了 birthbirth2 之间的区别,一个是方法,另一个是闭包。但是,两者都返回一个 Closure 对象,关于如何断言所有者和委托的问题仍未得到解答。这是:

class Mother {
    def prop = 'prop'
    def method(){ 'method' }
    Closure birth (param) {
        def local = 'local'
        def closure1 = {
            [ this, prop, method(), local, param ]
        }
        return closure1
    }

    def birth2 = { param ->
        def local = 'local'
        def closure2 = {
            [ this, prop, method(), local, param ]
        }
        return closure2
    }
}
Mother julia = new Mother()
def closure = julia.birth('param')
assert closure.owner == julia
assert closure.delegate == julia

def closure2 = julia.birth2('param')
assert closure2.owner ==  julia.birth2
assert closure2.delegate == julia.birth2

您当然是对的,closure2 的所有者和委托人是 birth2。闭包 2 的所有者是下一个持有它的对象,根据定义,它要么是一个类,要么是另一个闭包。请注意,所有者不能是我们在 closure1 的情况下看到的另一种方法。

闭包的委托是该委托解决其名称的上下文,默认情况下是所有者。在我们的例子中,closure2 的委托是 birth2。解决名称的 birth2 的上下文再次是​​默认情况下它的所有者,即类 Mother,这就是 propmethod() 在 {{1} 中已知的原因}.

然而,groovy 有一个很酷的特性,它允许您更改评估闭包的上下文,因此您可以为一个完全不相关的对象调用 closure2,公开与 closure2 相同的名称。这可以通过更改委托并使用 delegate.property 访问属性或仅更改隐式委托策略来实现。 见delegate of a closure

这是一个如何使用它的小例子:

Mother