我在clojure文件中有以下内容:
(ns helloworld
(:gen-class
:main -main))
(defn hello-world-fn []
(println "Hello World"))
(defn -main [& args]
(eval (read-string "(hello-world-fn)")))
我正在用
运行它lein run helloworld
我收到以下错误:
Exception in thread "main" java.lang.RuntimeException: Unable to resolve symbol:
helloworld in this context, compiling:(helloworld.clj:12)
我有一种感觉,我需要对ns-resolve
或resolve
做些什么,但我没有取得任何成功。我在主函数中尝试了以下内容:
(let [call-string (read-string "(hello-world-fn)")
func (resolve (symbol (first call-string)))
args (rest call-string)]
(apply func args))
没有成功。
某人(a)能指出我正确的方向; (b)准确解释Clojure读者在发生这种情况时会发生什么?
答案 0 :(得分:6)
尝试查看-main
内的实际命名空间。
(defn -main [& args]
(prn *ns*)
(eval (read-string "(hello-world-fn)")))
在用异常轰炸之前输出#<Namespace user>
。这暗示使用lein run
的程序的执行始于user
命名空间,显然不包含hello-world-fn
符号的映射。您需要明确限定它。
(defn -main [& args]
(eval (read-string "(helloworld/hello-world-fn)")))
答案 1 :(得分:3)
您可以使用macros
以非常优雅的方式解决您的挑战。实际上,您可以编写一个模仿eval
。
(defmacro my-eval [s] `~(read-string s))
(my-eval "(hello-world-fn)")); "Hello World"
它比eval
效果更好,因为s
的符号解析位于调用my-eval
的上下文中。感谢@Matthias Benkard的澄清。