0

我想将一小段代码从 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。

4

4 回答 4

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]

滚开!

于 2009-11-15T20:11:46.337 回答
1

在这种情况下,委托对象是一个没有 forEach 方法的 java.util.ArrayList 对象。

尽管如此,这个类的 Groovy 包装器有这个方法,但这里没有使用它(这似乎是一个错误)。

您可以使用delegate.forEach(). 我可以看到这打破了您所想到的 DSL,但也许它会让您更近一步。

以下代码适用于我:

def given(array,closure) {
    closure.delegate = array
    closure()
}

given([1,2,3,4]) {
   delegate.findAll { it > 4}
}
于 2009-11-16T19:57:08.137 回答
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更多信息,然后让我们知道哪些设置不正确。

于 2009-11-15T18:52:32.647 回答
0

尝试:

array.with(closure)

或者,如果您想保留语法:

def given(array,closure) {
    array.with(closure)
}
于 2009-12-28T22:14:01.117 回答