可以像调用带参数的函数一样调用 Groovy 对象吗?
Posted
技术标签:
【中文标题】可以像调用带参数的函数一样调用 Groovy 对象吗?【英文标题】:Can Groovy objects be invoked like functions with parameters? 【发布时间】: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
的可变参数签名。
【问题讨论】:
【参考方案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
的标准方法,不需要元编程。以上是关于可以像调用带参数的函数一样调用 Groovy 对象吗?的主要内容,如果未能解决你的问题,请参考以下文章
GroovyGroovy 方法调用 ( Groovy 构造函数中为成员赋值 | Groovy 函数的参数传递与键值对参数 | 完整代码示例 )