可以像带参数的函数一样调用Groovy对象吗?

时间:2012-11-20 15:57:26

标签: groovy metaprogramming metaclass

在Groovy中,我可以通过猴子修补元类“call方法使对象像函数一样调用:

myObject.metaClass.call = { "hello world" }
println myObject() // prints "hello world"

修补call只允许我调用没有参数的对象。有没有一种方法允许使用标准函数式语法调用参数?


编辑:一个答案正如tim_yates建议的那样,尽管ataylor的评论值得注意的是,如果没有明确的元编程,您可以简单地覆盖call

class MyType {
    def call(...args) {
        "args were: $args"
    }
}

def myObject = new MyType()
println myObject("foo", "bar") // prints 'args were ["foo", "bar"]'

显然,诀窍是使用...args的可变参数。

1 个答案:

答案 0 :(得分:7)

你可以这样做:

myObject.metaClass.call = { ...args -> "hello $args" }
assert myObject( 'one', 'two', 'three' ) == 'hello [one, two, three]'

(如你所见,args是一个对象数组)

或者是一个参数:

myObject.metaClass.call = { who -> "hello $who" }

或者,如果您希望将该单个参数作为可选参数,则可以执行以下操作:

myObject.metaClass.call = { who = null -> "hello ${who ?: 'world'}" }

assert myObject( 'tim' ) == 'hello tim'
assert myObject() == 'hello world'