gpt4 book ai didi

macros - Clojure:def 在顶层之外使用时丢弃 ^:macro

转载 作者:行者123 更新时间:2023-12-01 14:37:49 28 4
gpt4 key购买 nike

如果我评价

(def ^:macro my-defn1 #'defn)

定义了一个名为“my-defn1”的宏,我可以像使用“defn”一样使用它。

但是,如果我改为求值

(if true
(def ^:macro my-defn2 #'defn))

'my-defn2' 的 var 没有 :macro 元数据集,我不能将它用作宏,即使 '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

是什么让行为不同?

最佳答案

Clojure 的 def 不能真正有条件地应用。 def 的文档在 IMO 方面不够强大。这不仅仅是糟糕的风格,它会导致各种微妙的问题。

您应该只在顶层使用 def,或者在顶层以 dolet 形式使用。有条件地应用 def 将导致功能被拆分为类似 declare 和后续有条件的 def,但并不总是以您期望/喜欢的方式。

您最好在此处的顶层使用 def,然后有条件地使用 alter-var-root。或者使用 (def my-var (if .. .. ..))。想一想为什么您希望全局定义“消失”。

关于macros - Clojure:def 在顶层之外使用时丢弃 ^:macro,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18819490/

28 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com