在Groovy中将方法作为参数传递

Dav*_*les 36 groovy closures functional-programming

有没有办法在Groovy中将方法作为参数传递而不将其包装在闭包中?它似乎适用于函数,但不适用于方法.例如,给出以下内容:

def foo(Closure c) {
    c(arg1: "baz", arg2:"qux")
}

def bar(Map args) {
    println('arg1: ' + args['arg1'])
    println('arg2: ' + args['arg2'])
}
Run Code Online (Sandbox Code Playgroud)

这有效:

foo(bar)
Run Code Online (Sandbox Code Playgroud)

但如果bar是类中的方法:

class Quux { 
    def foo(Closure c) {
        c(arg1: "baz", arg2:"qux")
    }

    def bar(Map args) {
        println('arg1: ' + args['arg1'])
        println('arg2: ' + args['arg2'])
    }

    def quuux() { 
      foo(bar)
    }
} 

new Quux().quuux()
Run Code Online (Sandbox Code Playgroud)

没有这样的属性就失败了:类吧:Quux.

如果我将方法更改为包装bar在闭包中,它可以工作,但似乎不必要地冗长:

    def quuux() { 
      foo({ args -> bar(args) })
    }
Run Code Online (Sandbox Code Playgroud)

有更干净的方式吗?

epi*_*ian 60

.& 操作员来救援!

class Quux { 
    def foo(Closure c) {
        c(arg1: "baz", arg2:"qux")
    }

    def bar(Map args) {
        println('arg1: ' + args['arg1'])
        println('arg2: ' + args['arg2'])
    }

    def quuux() { 
      foo(this.&bar)
    }
} 

new Quux().quuux()
// arg1: baz
// arg2: qux
Run Code Online (Sandbox Code Playgroud)

在一般情况下,obj.&method会返回一个绑定的方法,即调用封闭methodobj.


Mai*_*cio 3

除了方法指针运算符( .&) 之外,对于Groovy 版本 3.0.0 及更高版本,还有等效的、兼容的、众所周知的 Java 8+方法引用运算符( ::)。

\n
def foo(Closure c) {\n    c(func: "foo")\n}\n\ndef bar(Map args = [:]) {\n    println "$args.func bar"\n}\n\nprintln foo(this::bar)\n
Run Code Online (Sandbox Code Playgroud)\n

输出:

\n
foo bar\n
Run Code Online (Sandbox Code Playgroud)\n

方法引用运算符,如Groovy 文档中所述:

\n
\n

[\xe2\x80\xa6] 与 Groovy\xe2\x80\x99s\n方法指针运算符提供的功能有些重叠。事实上,对于动态 Groovy,方法引用运算符只是方法指针运算符的别名。对于静态 Groovy,该运算符生成的字节码类似于 Java 为同一上下文生成的字节码。

\n
\n