常规关闭的所有者
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
根据文档,在这两种情况下,birth
和 birth2
都是闭包。在这些闭包中,我们声明了closure1
和closure2
。我给他们起名字只是为了指代他们。这些closure1
和closure2
的所有者应参考birth
和birth2
。根据官方文档。但在第一个示例中,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】:
您已经了解了birth
和birth2
之间的区别,一个是方法,另一个是闭包。但是,两者都返回一个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
类,这就是prop
和method()
在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."
【讨论】:
以上是关于常规关闭的所有者的主要内容,如果未能解决你的问题,请参考以下文章
如何将流式 DataFrame 转换为常规批处理 DataFrame? [关闭]
在 redux 中使用 thunk 中间件与使用常规函数作为异步操作创建者相比有啥好处? [关闭]