常规关闭的所有者

Posted

技术标签:

【中文标题】常规关闭的所有者【英文标题】:Owners in groovy closures 【发布时间】:2016-07-15 14:42:03 【问题描述】:

根据“Groovy in Action”,可以通过多种方式声明闭包。几种方法: def 打印机 = 行 -> println 行 def 闭包 getPrinter() 返回 行 -> println 行

根据Closures, official documentationowner在关闭

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

好的,我们来看看:

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

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

谁能解释一下区别?

【问题讨论】:

【参考方案1】:

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

birth2 是一个闭包

这就是区别

【讨论】:

这意味着当我声明时在类内部: def Closure getPrinter() return line -> println line 它是一个方法,而不是一个闭包。在这种情况下,明确的“关闭”意味着什么? 这是返回类型。所以它是一个返回闭包的方法。 int add(int a, int b) a + b 是一个接受两个int并返回一个int的方法,Closure method(String a) -> a * 2 是一个接受一个字符串并返回一个闭包的方法 Closure clos = String a -> -> a * 2 是一个闭包,它接受一个字符串,并返回一个闭包【参考方案2】:

您已经了解了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。闭包的所有者是下一个持有它的对象,根据定义,它要么是一个类,要么是另一个闭包。请注意,所有者不能是我们在closure1 的情况下看到的另一种方法。

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

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

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

class Person 
    String name
    int age
    def describe =  "$name is $age years old." 

person = new Person(name: 'John', age: 42)
assert person.describe() == "John is 42 years old."

closure = person.describe
closure.resolveStrategy = Closure.DELEGATE_FIRST
closure.delegate = [name: 'Mike', age:'66']
assert closure() == "Mike is 66 years old."

【讨论】:

以上是关于常规关闭的所有者的主要内容,如果未能解决你的问题,请参考以下文章

将军事时间转换为常规时间c#和sql [关闭]

如何将流式 DataFrame 转换为常规批处理 DataFrame? [关闭]

如何创建打开/关闭 collectionView 部分

在 redux 中使用 thunk 中间件与使用常规函数作为异步操作创建者相比有啥好处? [关闭]

使用 Node.js 选择哪个数据库(NoSQL 或常规 SQL)最好? [关闭]

为什么可以将int []作为通用类型参数,但不能将int作为常规类型参数? [关闭]