在Groovy中,您是否可以获得对本地或静态导入方法的方法引用而无需重新创建类?

时间:2015-06-11 17:05:47

标签: groovy

理想情况下,我希望能够表达这个想法:“代码中当前位置foo()会调用的任何内容,请给我一个方法参考foo”。

基本原理:我正在研究一些使用大量高阶函数和函数组合的代码。我想:a)尽可能简洁,b)不必 当我在类之间重构和移动函数时,继续编辑分散在代码周围的类名。

例如:

/* ---- foo.pkg1.Utils.groovy */
public final class Utils {

    private Utils() { /* as it's all static methods */ }

    static foo() { 42; }

}

/* ---- foo.pkg2.Client1.groovy */
import foo.pkg1.Utils

def f1 = Utils.&foo // <-- restates class (but works)
println f1()

/* ---- foo.pkg2.Client2.groovy */
import static foo.pkg1.Utils.*

def f2 = foo  // <-- No!
// "groovy.lang.MissingPropertyException: No such property: foo ..."
println f2() 

def f3 = &foo  // <-- No!
// "unexpected token: & at line: 17, column: 14"
println f3()

def f4 = this.&foo  // <-- Also no!
// "groovy.lang.MissingMethodException: No signature of method..."
println f4()

/* ---- foo.pkg2.Client3.groovy */
/* My best attempt ... but this only allows me to change which
   class 'u' refers too, not to create a method reference to
   whatever `foo()` would call at the same place in the code. */
import static Utils as u

def f5 = u.&foo
println f5()

2 个答案:

答案 0 :(得分:1)

由于变量命名被限制为with次序,因此略有错误,但它是:

    class Util {
        static foo(arg) { "foo $arg" }
        static bar() { "bar" }
        static batman(fn) { fn("captain") }
    }

    def (foo, bar, batman) = Util.with { [it.&foo, it.&bar, it.&batman] }

    assert foo("eck") == "foo eck"

    assert batman(foo) == "foo captain"

如果您始终使用脚本,则使用binding类的反射处理脚本自己的Util也是一种选择。

答案 1 :(得分:0)

您可以将MethodClosure定义为类Utils的私有静态属性,如:

import org.codehaus.groovy.runtime.MethodClosure

public final class Utils {
    private static final MethodClosure fooPointer = this.&foo
    private Utils() { }
    static foo() { 42 }
}

// Client
import static Utils.*
def f1 = fooPointer
println f1()

不知道怎么会有利。