簡體   English   中英

如何從Java調用Clojure可變參數函數

[英]How to call a Clojure variadic function from Java

是否有可能在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包裝器方法,但是如果可能的話我想避免這種情況。

我建議在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[] {...}東西)。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM