作为闭包调用方法

6

我对Groovy运算符.&的理解是它将方法调用转换为闭包。因此,以下代码(可在Groovy控制台中运行)应该可以工作:

class Foo {
  def method(def param) {
    param + 10
  }
}

def invokeClosure = {Closure closure ->
   return closure.call()
}

def f = new Foo()
invokeClosure f.&method(6)

当然,如果我将最后一行更改为
invokeClosure {f.method(6)}

它能正常工作,但是我对于.&运算符的理解有什么问题呢?

谢谢, Don

3个回答

9
使用.&符号将方法转换为闭包时,不需要输入参数。f.&method(6)与调用f.method(6)相同,它将返回16,因此在您的示例中,您传递的是16而不是闭包到invokeClosure中。这会导致以下异常,因为Integer类没有call方法:Exception thrown: No signature of method: java.lang.Integer.call()。下面将f.method的方法指针传递给invokeClosure,并且这通常是使用.&的方式。
class Foo {
  def method(def param) {
    param + 10
  }
}

def invokeClosure = {Closure closure ->
   return closure.call(6) // can leave off .call
}

def f = new Foo()
invokeClosure f.&method

正如你所指出的,以下内容可以正常工作:

invokeClosure {f.method(6)}

这是因为你传递了一个不带参数的闭包,所以在这种情况下,closure.call()可以正常工作。


1
实际上,严格来说,我认为 {f.method(6)} 是一个接受一个参数的闭包,而 {-> f.method(6)} 是一个不接受参数的闭包。非常好的答案,谢谢! - Dónal

1
请使用 invokeClosure f.&method.curry(6)。这是一个可以无需参数调用的闭包。

0

上面的示例还可以扩展,将参数作为参数传递到invokeClosure中。这将为您提供预期的结果和语法。

class Foo {
  def method(def param) {
    param + 10
  }
}

def invokeClosure = {Closure closure, def parameter ->
   return closure.call(parameter) 
}

def f = new Foo()
invokeClosure f.&method, 6

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接