如果我评估
(def ^:macro my-defn1 #'defn)定义了一个名为'my-defn1‘的宏,我可以像使用'defn’一样使用它。
但是,如果我评估
(if true
(def ^:macro my-defn2 #'defn))“my-defn2”的var没有设置:宏元数据,即使'def‘形式与前面的大小写相同,我也不能将其用作宏。
下面是完整的代码(http://cljbin.com/paste/52322ba5e4b0fa645e7f9243):
(def ^:macro my-defn1 #'defn)
(if true
(def ^:macro my-defn2 #'defn))
(println (meta #'my-defn1)) ; => contains :macro
(println (meta #'my-defn2)) ; => doesn't contain :macro!
(my-defn1 hello1 []
(println "hello 1"))
(hello1) ; => prints "hello 1"
(my-defn2 hello2 [] ; => CompilerException: Unable to resolve
(println "hello 2")) ; symbol: hello2 in this context是什么让这种行为不同呢?
发布于 2013-09-16 14:59:10
Clojure的def不能真正有条件地应用。关于def的文档在这方面是不够强大的。这不仅仅是糟糕的风格,它可能会导致各种微妙的问题。
您应该只在顶层使用def,或者在顶层使用do或let表单。有条件地应用def将导致功能被拆分成类似于declare和随后的条件def,但并不总是以您期望/喜欢的方式。
你最好在这里的顶层使用def,然后有条件地使用alter-var-root。或者使用(def my-var (if .. .. ..))。想想为什么你会想要有一个全局的定义“消失”。
https://stackoverflow.com/questions/18819490
复制相似问题