3

我在 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我有一种感觉,我需要与or做点什么,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 阅读器中发生了什么?

4

2 回答 2

6

尝试查看您的-main.

(defn -main [& args]
  (prn *ns*)
  (eval (read-string "(hello-world-fn)")))

#<Namespace user>在轰炸之前输出,但除外。这暗示程序的执行lein runuser命名空间开始,显然不包含hello-world-fn符号的映射。您需要明确限定它。

(defn -main [& args]
  (eval (read-string "(helloworld/hello-world-fn)")))
于 2012-02-06T13:24:57.413 回答
3

你可以用一种非常优雅的方式解决你的挑战,使用macros. 事实上,你可以编写一个模仿eval.

(defmacro my-eval [s] `~(read-string s))
(my-eval "(hello-world-fn)")); "Hello World"

它工作得更好,eval因为 的符号解析s发生在调用my-eval. 感谢@Matthias Benkard 的澄清。

您可以在http://clojure.org/reader中阅读有关宏及其语法的信息

于 2012-02-07T07:12:28.343 回答