我只是不明白如何让闭包像我期望的那样工作。
class Bar {
public void greeting(String name) {
println "Hello: ${name}"
}
}
当我在Closure
中委托Bar
时,如下所示:
class Foo {
void helloBob(){
bar {
greeting("Bob")
}
}
def bar(@DelegatesTo(value = Bar, strategy = Closure.DELEGATE_ONLY) Closure cl) {
cl.rehydrate(new Bar(), this, this)
cl.call()
}
static void main(String[] args) {
new Foo().helloBob()
}
}
我在运行时得到了堆栈跟踪:
Exception in thread "main" groovy.lang.MissingMethodException: No signature of method: Foo.greeting() is applicable for argument types: (String) values: [Bob]
Possible solutions: getAt(java.lang.String)
at org.codehaus.groovy.runtime.ScriptBytecodeAdapter.unwrap(ScriptBytecodeAdapter.java:70)
at org.codehaus.groovy.runtime.callsite.PogoMetaClassSite.callCurrent(PogoMetaClassSite.java:76)
at
at ...
:No signature of method: Foo.greeting()
对我来说没有意义,因为它应该调用Bar.greeting()
,就像它在Closure
中调用@DelegatesTo(value = Bar
一样。为什么闭包没有引用Bar.greeting
?我如何让它这样做?我的IDE(IntelliJ)似乎认为它是我想要的Bar.greeting
,但当我运行它时,我得到了一个堆栈跟踪。
***EDIT***奇怪的是,如果我删除了一大堆类型信息,那么它似乎可以使用以下代码:
Bar bar(closure) {
def bar = new Bar()
closure.delegate = bar
// closure.rehydrate(bar, this, this) // this causes error why?
closure.call()
return bar
}
我也不明白为什么我不能使用rehydrate
,它似乎会导致错误,但手动设置delegate
是好的。
1条答案
按热度按时间weylhg0b1#
Rehydrate并不修改闭包--它返回闭包的一个新副本,所以调用新闭包。
不要忘记将resolveStrategy设置为您在注解中声明的内容。