11

Javaからvarargsメソッドとして呼び出すことができるClojureで可変関数を宣言することは可能ですか?

開発中のいくつかのコードからのこの抜粋を検討してください。

(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 で non-variadic を呼び出す varargs ラッパー メソッドを記述できることはわかっていますがexprFactory、可能であればそれは避けたいと思います。

4

1 に答える 1

1

clojure.lang.AFn の「 applyToHelper」のようなヘルパー関数を Java 側で作成することをお勧めします。

これは、次のような 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
     }
   }

これは少しハックであり、clojure.lang.IFnの内部定義に依存しますが、少なくとも Java 側で比較的優れた可変引数構文が得られます (つまり、そのようなことを行う必要はありませnew Object[] {...}ん)。

于 2012-05-03T04:03:34.153 に答える