Groovy Closure方法不优先在类中似乎不被调用

ttisahbt  于 2022-11-01  发布在  其他
关注(0)|答案(1)|浏览(234)

我只是不明白如何让闭包像我期望的那样工作。

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是好的。

weylhg0b

weylhg0b1#

Rehydrate并不修改闭包--它返回闭包的一个新副本,所以调用新闭包。

cl.rehydrate(new Bar(), this, this).call()

不要忘记将resolveStrategy设置为您在注解中声明的内容。

相关问题