我对嵌套闭包中的Groovy委派策略感到困惑。这是一个简化的示例:
class Clazz {
String name
String whoAmI() {
return name
}
void doit(Clazz clazz) {
def cl = {
println "Outer closure: resolveStrategy=${resolveStrategy}, " +
"implicit=${whoAmI()}, delegated=${delegate.whoAmI()}"
{->
println "Inner closure: resolveStrategy=${resolveStrategy}, " +
"implicit=${whoAmI()}, delegated=${delegate.whoAmI()}"
}.call()
}
cl.resolveStrategy = Closure.DELEGATE_FIRST
cl.delegate = clazz
cl()
}
}
def a = new Clazz(name: 'A')
def b = new Clazz(name: 'B')
a.doit(b)
输出:
外部闭包:resolveStrategy = 1,隐式= B,委托= B
内部闭包:resolveStrategy = 0,隐式= A,委托= B
为什么 resolveStrategy 不能传播到内部闭包?设置解决方案策略的目的是改变隐式 this 的解决方式。但是,如果它没有在闭包内部传播,那么该机制似乎和无用一样好。在Groovy中,闭包是如此普遍,以至于没有它们,几乎很难写几行。
答案 0 :(得分:1)
大约五年前发现了一个类似的问题:Nested closure resolution different between methods and properties?显然是一个错误,此后一直没有任何动静地打开过:https://issues.apache.org/jira/browse/GROOVY-7232
链接的帖子中还提到了一些我也注意到的内容:属性已正确解析为委托,但不是方法调用。这是一个经过重做的示例来证明这一点:
class Clazz {
String name
void doit(Clazz clazz) {
def cl = {
println "Outer closure: property=${name}, method=${getName()}"
{->
println "Inner closure: property=${name}, method=${getName()}"
}.call()
}
cl.resolveStrategy = Closure.DELEGATE_FIRST
cl.delegate = clazz
cl()
}
}
def a = new Clazz(name: 'A')
def b = new Clazz(name: 'B')
a.doit(b)
结果:
Outer closure: property=B, method=B Inner closure: property=B, method=A
链接帖子中的某人使用 rehydrate 发布了一种解决方法。就我而言,它只有在替换了所有引用(包括 this !
)时才起作用(某种程度上)!class Clazz {
String name
void doit(Clazz clazz) {
def cl = {
println "Outer closure: property=${name}, method=${getName()}"
{->
println "Inner closure: property=${name}, method=${getName()}"
}.call()
}
cl.rehydrate(clazz, clazz, clazz)()
}
}
def a = new Clazz(name: 'A')
def b = new Clazz(name: 'B')
a.doit(b)
结果:
Outer closure: property=B, method=B Inner closure: property=B, method=B