在 Scala 中,如果有一个对象 Foo
具有 apply(x: Int)
我可以用 Foo(42)
调用它(作为 Foo.apply(42)
的简写)。
是否可以在 Java 或 Groovy 中复制它?我原以为 Groovy 的 call
的功能可能相似,但 def call(int x)
或 static def call(int x)
都没有调用 调用
编辑:根据要求添加示例 DSL
典型/现有 DSL:alter 't' add 'a' storing BAR
(其中 BAR
是枚举)。
尝试添加一些东西来代替上面的 BAR
但会接受一个参数,但不会太多地改变语法,理想情况下:alter 't ' 添加 'a' 存储 FOO(42)
我已经将 FOO 创建为一个带有接受 int 的构造函数的类 - 我现在正在寻找的是一种通过 FOO(42)
而不是 调用该构造函数的方法新的 FOO(42)
或 FOO.call(42)
最佳答案
在 Groovy 中最直接的方法是在类上编写一个 static call()
方法,但它不会使 Clazz()
工作。这可能是一个错误,但我找不到关于它的 JIRA。
我想建议使用闭包:
import groovy.transform.Canonical as C
@C class Bar { def bar }
@C class Baz { def baz }
A = { new Bar(bar: it) }
B = { new Baz(baz: it) }
assert A("wot") == new Bar(bar: "wot")
assert B("fuzz") == new Baz(baz: "fuzz")
更新:类名似乎在被调用者上下文中被解析为静态方法调用,这有效(但它在 DSL 中不可用):
class A {
static call(str) { str.toUpperCase() }
}
assert ((Class)A)("qwop") == "QWOP"
更新 2:根据您的 DSL 示例,移除括号是否可行?
class FOO {}
def params = [:]
alter = {
params.alter = it
[add : {
params.add = it
[storing: {
params.clazz = it
[:].withDefault { params.param = it }
}]
}]
}
alter 't' add 'a' storing FOO 42
assert params == [
alter : 't',
add : 'a',
clazz : FOO,
param : '42'
]
关于Java(或 Groovy)相当于 Scala 的 apply,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25920617/