1

我想声明一个 Clojure 函数并立即使用 clojure-utils 在 Java 代码中对其进行评估。这个怎么做?

我正在使用的代码是这样的:

public static void main(String[] args) {

    String s = "(defn fun[lst] (map #(/ % 2) lst))" +
               "(list* (#'clojure.core/fun '(1 2 3 4 5)))";
    System.out.println("Evaluating Clojure code: " + s);
    Object result = mikera.cljutils.Clojure.eval(s);
    System.out.println("=> " + result);
}

如果我只是在字符串变量中使用以下表达式s,它将正常工作:

(list* (map #(/ % 2) '(1 2 3 4 5)))

Java 编译器将显示:

=> (1/2 1 3/2 2 5/2)

但是,如果我尝试同时声明我的函数,然后尝试从代码中调用它,如下所示:

String s = "(defn fun[lst] (map #(/ % 2) lst))" 
         + "(list* (fun '(1 2 3 4 5)))";

编译器只会显示:

Evaluating Clojure code:

(defn fun[lst] (map #(/ % 2) lst))(list* (#'clojure.core/fun '(1 2 3 4 5)))
=> #'clojure.core/fun

更新:我写了这个结构,很糟糕,但它有效:

String s = 
"(do 
    (defn main[lst]

      (defn fun[lst]
        (map #(/ % 2) lst))

      (list* (fun lst))) 

    (main '(1 2 3 4 5)))"

结果: => (1/2 1 3/2 2 5/2)

更新 2(固定):

(do 
    (defn fun[lst]
        (map #(/ % 2) lst))

    (list* (fun '(1 2 3 4 5))))
4

2 回答 2

2

它不是 REPL,因此它只会读取一个 s 表达式并对其进行评估。你应该评估每一个。

public static void main(String[] args) {
    clojure("(defn fun[lst] (map #(/ % 2) lst))");
    clojure("(list* (#'clojure.core/fun '(1 2 3 4 5)))");
}

public static Object clojure(String s) {
    System.out.println("Evaluating Clojure code: " + s);
    Object result = mikera.cljutils.Clojure.eval(s);
    System.out.println("=> " + result);
    return result;
}
于 2014-06-15T10:03:10.057 回答
2

您只是在使用字符串评估。但是直接使用与 Clojure 的互操作更为明显。

例如,您可以使用 load-string 函数:

IFn loadString = Clojure.var("clojure.core", "load-string");
Object result = loadString.invoke("(println \"Appel\")(your clojure code)");

关于互操作性:http ://clojure.github.io/clojure/javadoc/

于 2014-06-15T10:53:50.547 回答