簡體   English   中英

Clojure - (讀取字符串字符串調用函數

[英]Clojure - (read-string String calling function

我在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-resolveresolve但我沒有取得任何成功。 我在main函數中嘗試了以下內容:

(let [call-string  (read-string "(hello-world-fn)")
      func (resolve  (symbol (first call-string)))
      args (rest call-string)]
   (apply func args))

沒有成功。

有人(a)可以指出我正確的方向; (b)准確解釋Clojure讀者在發生這種情況時會發生什么?

嘗試查看-main的實際命名空間。

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

它在輸出異常之前輸出#<Namespace user> 這暗示了lein run程序的lein runuser命名空間開始,顯然不包含hello-world-fn符號的映射。 您需要明確限定它。

(defn -main [& args]
  (eval (read-string "(helloworld/hello-world-fn)")))

您可以使用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中閱讀有關宏及其語法的內容

暫無
暫無

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

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