gpt4 book ai didi

Java -> Clojure -> Java

转载 作者:塔克拉玛干 更新时间:2023-11-03 03:53:31 26 4
gpt4 key购买 nike

我正在尝试使用 Clojure 作为宿主 Java 程序的脚本语言。这个想法是最终用户将能够编写调用特定领域 Java API 的 Clojure 脚本代码。在运行时,宿主 Java 程序将评估最终用户的 Clojure 脚本(它将依次调用域 API)。所以我从一个非常简单的原型(prototype)开始探索地形。

package a.problem.domain;

public class Domain {

public Domain() { }

public String defaultMsg() {
return "default";
}

public String passBackMsg(String s) {
return s;
}
}

宿主Java程序

(为简单起见对最终用户的 Clojure 脚本进行了硬编码)

String script = "(do                                    "+
" (import '(a.problem.domain Domain)) "+
" (.defaultMsg (Domain.)) "+
") ";
System.out.println(RT.var("clojure.core", "eval").invoke(RT.var("clojure.core","read-string").invoke(script)));

(代码片段取自 here )

到目前为止一切顺利。

但是我找不到调用第二种方法(需要参数的方法)的方法。相反,我求助于在运行时动态生成 Clojure 脚本,并将占位符替换为表示调用域方法 passBackMsg 结果的文字。显然,这不能令人满意并且不会走得太远(如果我想将 java.sql.Connection 传递给我的 Clojure 脚本怎么办?)。

那么,如何从宿主 Java 程序中调用 passBackMsg 方法呢?

当我尝试以下操作时:

String script = "(ns foo)                                   "+ 
"(import '(a.problem.domain Domain)) "+
"(defn numberToString [s] ( "+
" (.passBackMsg (Domain.) s) "+
")) ";
RT.var("clojure.core", "eval").invoke(RT.var("clojure.core","read-string").invoke(script)); // line-A
System.out.println(RT.var("foo", "numberToString").invoke(33)); // line-B

我得到:

java.lang.IllegalStateException: Can't change/establish root binding of: *ns* with set

... 在 A 行。当我尝试不使用 ns 并使用:

RT.var("user", "numberToString").invoke(33)

(“用户”是一个疯狂的猜测,因为我没有看到没有命名空间参数的 var 方法)

我得到一个:

java.lang.IllegalStateException: Attempting to call unbound fn: #'user/numberToString"

...在 B 行。

最佳答案

试试这个:

String script = "(do                                    "+
" (import '(a.problem.domain Domain)) "+
" (fn [s] " +
" (.passBackMsg (Domain.) s) "+
")) ";

IFn fn = (IFn)RT.var("clojure.core", "eval").invoke(RT.var("clojure.core","read-string").invoke(script));

fn.invoke("hello");

更新:下面的示例代码工作正常:

package hello_clj;

import clojure.lang.RT;
import clojure.lang.IFn;

public class Main {

public String passBackMsg(String s) {
return s;
}

public static void main(String[] args) {
String script = "(do (import 'hello_clj.Main) (fn [s] " +
"(.passBackMsg (Main.) s) ))";

IFn fn = (IFn)RT.var("clojure.core", "eval").invoke(RT.var("clojure.core","read-string").invoke(script));
System.out.print(fn.invoke("Hello"));
}

}

关于Java -> Clojure -> Java,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14987910/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com