如何从Java调用Clojure可变参数函数

Dav*_*oll 11 java interop clojure variadic-functions

是否有可能在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)))
Run Code Online (Sandbox Code Playgroud)

有什么我可以代替?????允许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);
Run Code Online (Sandbox Code Playgroud)

为了使这一点更清楚,我知道我用Object它代替?????exprFactory改为:

(defn -exprFactory
  ; interface method called from Java
  [idStr funcStr argsArray]
  (apply expr-factory idStr funcStr (seq argsArray)))
Run Code Online (Sandbox Code Playgroud)

..但这意味着我必须像这样编写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 }));
Run Code Online (Sandbox Code Playgroud)

再一次,我知道我可以在Java中编写一个调用非可变参数的varargs包装器方法exprFactory,但是如果可能的话我想避免这种情况.

mik*_*era 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
     }
   }
Run Code Online (Sandbox Code Playgroud)

这有点麻烦,取决于clojure.lang.IFn的内部定义,但至少你会在 Java 端获得相对不错的可变参数语法(即不需要做这些new Object[] {...}事情)。