我想将一小段代码从Ruby移植到Groovy,而我却陷入了困境:
def given(array,closure) {
closure.delegate = array
closure()
}
given([1,2,3,4]) {
findAll { it > 4}
}
现在它已经消失了这条消息:
Exception thrown: Cannot compare ConsoleScript0$_run_closure1 with value 'ConsoleScript0$_run_closure1@1e6743e' and java.lang.Integer with value '4'
。
我试图将闭包的委托设置为数组,但似乎在findAll
方法中,它表示一个闭包,而不是数组中的实际项。我也尝试像这样运行闭包:
array.with {
closure(array)
}
但我仍然无法使其发挥作用。关于什么可行的任何想法? Ruby的等价物是instance_eval
数组上下文中的闭包。
编辑:运行Mykola的代码产生了这个输出:
given [1, 2, 3, 4]
class Demo$_main_closure1
2
Exception thrown: Cannot compare Demo$_main_closure1 with value 'Demo$_main_closure1@fe53cf' and java.lang.Integer with value '2'
groovy.lang.GroovyRuntimeException: Cannot compare Demo$_main_closure1 with value 'Demo$_main_closure1@fe53cf' and java.lang.Integer with value '2'
at Demo$_main_closure1_closure2.doCall(ConsoleScript3:15)
at Demo$_main_closure1.doCall(ConsoleScript3:15)
at Demo$_main_closure1.doCall(ConsoleScript3)
at Demo.given(ConsoleScript3:28)
at Demo$given.callStatic(Unknown Source)
at Demo.main(ConsoleScript3:12)
我正在运行Groovy 1.6.5。
答案 0 :(得分:1)
对我来说这看起来像个错误。这是代码
class Demo {
static def main(args) {
given([1, 2, 3, 4]) {
println getClass()
println size()
grep { v -> v > 2 }
}
}
static def size() {
return 2
}
static def given(object, closure) {
println 'given ' + object
closure.resolveStrategy = Closure.DELEGATE_ONLY
closure.delegate = object
closure()
}
}
必须打印(我倾向于认为)'4'作为一个尺寸。实际上,如果您要评论方法'大小',它会打印出来。
您可以阅读有关resolveStrategy
的内容,然后告诉我们未正确设置的内容。
答案 1 :(得分:1)
简单 - 你试图调用一个闭包传递一个数组,其中findAll
应该在数组本身上调用。
以下是一些可能的解决方案。第一个是直截了当的:
def given(array,closure) {
closure(array)
}
println "first way result: " +
given ( [1,2,3,4,5] ) { it.findAll { it > 4 } }
或者您可以将findAll
封装在方法体中(这取决于您实际上要做的事情):
def given(array,closure) {
array.findAll(closure)
}
println "second way result: " +
given( [1,2,3,4,5] ) { it > 4 }
以下是两者的结果:
first way result: [5]
second way result: [5]
走开了!
答案 2 :(得分:1)
在这种情况下,委托对象是一个java.util.ArrayList对象,它没有forEach方法。
然而,这个类的Groovy包装器有这个方法,但是这里没有使用它(这个接缝是一个bug)。
您可以使用delegate.forEach()
解决此问题。我可以看到这打破了你想到的DSL,但也许它会让你更近一步。
以下代码适用于我:
def given(array,closure) {
closure.delegate = array
closure()
}
given([1,2,3,4]) {
delegate.findAll { it > 4}
}
答案 3 :(得分:0)
尝试:
array.with(closure)
或者如果你想保留你的语法:
def given(array,closure) {
array.with(closure)
}