在clojure中,宏为程序员提供了巨大的力量。 eval
也非常强大。两者之间存在一些细微差别。我希望这个谜语能够对这个话题有所启发。
(ns hello)
(defmacro my-eval [x] `~(read-string x))
(defn hello[] "Hello")
(defn run-stuff []
(println (hello))
(println (my-eval "(hello)"))
(println (eval (read-string "(hello)"))))
(ns main)
(try (hello/run-stuff)
(catch Exception e (println e)))
在run-stuff
正文中的3个陈述中,哪一个引起异常,为什么其他异常没有?
在调查这个漂亮的问题Clojure - (read-string String calling function之后,我制定了以下谜语。感谢@Matthias Benkard的澄清
答案 0 :(得分:4)
(println (hello))
和(println (my-eval "(hello)"))
是完全相同的陈述 - 唯一的区别是会让您的编辑更加困惑。 my-eval
与真实eval
无法比较。区别在于my-eval
的参数在编译时需要是一个字符串 - 以下错误因为符号x
无法转换为字符串。
(def x "(hello)")
(my-eval x)
这使得my-eval
毫无意义 - 您可以“评估”文字字符串,或者您可以删除引号和my-eval
并具有相同功能的代码(您的编辑将会理解)。
Real eval
尝试在运行时编译代码。在这里,它失败了,因为它是从main
命名空间而不是hello
命名空间运行的,正如@Matthias Benkard指出的那样。