是否可以在Clojure中声明一个可以从Java调用varargs方法的可变参数函数?
从开发中的一些代码中考虑这个摘录:
(ns com.mydomain.expression.base
(:gen-class
:name com.mydomain.expression.Base
:methods [^:static [exprFactory [String String ?????] Object]]
)
(defn expr-factory
; worker function that is also called from Clojure
[id func & args]
(let [ex ("construction code here")]
ex))
(defn -exprFactory
; interface method called from Java
[idStr funcStr & argsArray]
(apply expr-factory idStr funcStr (seq argsArray)))
有什么我可以代替?????
来允许Java调用exprFactory
方法并知道它是一个varargs方法:
import com.mydomain.expression.Base;
...
Object e1 = Base.exprFactory("e1", "day");
Object e2 = Base.exprFactory("e2", "length", "string");
Object e3 = Base.exprFactory("e3", "*", 4, 5);
Object sum = Base.exprFactory("sum", "+", e1, e2, e3);
为了更清楚一点,我知道我使用Object
代替?????
并将exprFactory
更改为:
(defn -exprFactory
; interface method called from Java
[idStr funcStr argsArray]
(apply expr-factory idStr funcStr (seq argsArray)))
..但这意味着我必须像这样编写Java调用:
import com.mydomain.expression.Base;
...
Object e1 = Base.exprFactory("e1", "day", new Object[0] ));
Object e2 = Base.exprFactory("e2", "length", new Object[] { "string" }));
Object e3 = Base.exprFactory("e3", "*", new Integer[] { 4, 5 }));
Object sum = Base.exprFactory("sum", "+", new Object[] { e1, e2, e3 }));
同样,我知道我可以在Java中编写一个调用非变量exprFactory
的varargs包装器方法,但如果可能的话我想避免这种情况。
答案 0 :(得分:1)
我建议在Java端编写辅助函数,类似clojure.lang.AFn中的“applyToHelper”
这将采用Java函数的形式,如下所示:
public Object invokeVariadic(IFn function, Object... args) {
switch (args.length) {
case 0:
return function.invoke();
case 1:
return function.invoke(args[0]);
/// 20-odd more cases
}
}
这有点像hack并依赖于clojure.lang.IFn的内部定义,但至少你会在Java端获得相对不错的可变参数语法(即不需要执行new Object[] {...}
的东西)