【问题标题】:Can Groovy objects be invoked like functions with parameters?可以像调用带参数的函数一样调用 Groovy 对象吗?
【发布时间】:2012-11-08 17:54:57
【问题描述】:

在 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 的可变参数签名。

【问题讨论】:

    标签: groovy metaprogramming metaclass


    【解决方案1】:

    你可以这样做:

    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'
    

    【讨论】:

    • 嗯...我可以发誓我试过这个但它没有用,但再次尝试似乎证明它确实有效。
    • 虽然问题是专门关于通过元类添加行为的,但值得注意的是,这也适用于名为 call 的标准方法,不需要元编程。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-06-25
    • 1970-01-01
    • 1970-01-01
    • 2013-11-14
    • 2013-04-15
    • 1970-01-01
    相关资源
    最近更新 更多