我有一个Groovy特性需要提供一个配置Closure作为库方法调用的参数(它是HttpBuilder,但它应该没关系)。
为了重现这个问题,我创建了以下简单示例:
trait T {
def doIt() {
return {
n = 1
}
}
}
class Delegate {
int n
}
class Tish implements T {
def go() {
def closure = doIt()
def d = new Delegate()
closure.delegate = d
closure()
assert d.n == 1
}
}
new Tish().go()
预计这会运行没有错误,因为当运行doIt()
特征中的T
方法返回的闭包时,其委托被设置为可以设置n
变量的东西到1 ....
但是,这不起作用,我收到此错误:
groovy.lang.MissingPropertyException: No such property: n for class: Tish
如果我将T
作为一个课程,让Tish
代替它,那么它就可以了!
我尝试更改Closure的委托策略,但这没有帮助。
这是一个Groovy错误还是有办法解决这个问题?
答案 0 :(得分:1)
好吧,我找到了一个解决方法......但是,知道这是一个bug是否很有趣,如果是,那么什么时候Groovy团队会修复它!
更新:this is a bug并希望在不久的将来修复Groovy版本!
在config Closure中进行的所有调用都可以通过调用getDelegate()
方法获取实际的Delegate对象,然后直接在其上设置所有属性,如下所示:
return {
def d = getDelegate()
d.n = 1
}
不理想,但让我失望,希望它能帮助别人......
编辑: 正如@bdkosher在评论中所指出的,另一个解决方案是在闭包中使用setter语法:
return {
setN 1
}
答案 1 :(得分:0)
从
更改代码<canvas id="canvas"></canvas>
到
def d = new Delegate()
closure.delegate = d
closure()
这解决了一个非常相似的问题,我在Grails 3.3.8,Groovy 2.4.15,Java 1.8.0_131中遇到过。不知道为什么,但是有帮助。
我正试图找出错误并添加以下输出
def d = new Delegate()
closure.delegate = d
closure.run()
并发现在第一种情况下,println this
println owner
println delegate
甚至在执行delegate
之前就已经设置closure.delegate = d
都没有改变!如果调用了closure()
,那么closure.run()
的设置正确!!!