【问题标题】:Why does `(def ^:private name 1 ) eval to (def namespace/name 1)?为什么`(def ^:private name 1) eval to (def namespace/name 1)?
【发布时间】:2014-01-03 13:36:51
【问题描述】:

为什么会这样:

`(def ^:private name 1 )

评估为:

(def namespace/name 1) 

而不是这个:

(def ^:private namespace/name 1) 

我只是想写一个小宏:

(defmacro def- [name val] `(def ^:private ~name ~val))

但它扩展为:

(macroexpand-1 `(def- foo 12))
=> (def namespace/foo 12)

【问题讨论】:

  • 你知道元数据是如何工作的吗?
  • 不抱歉,也许我应该这样挖,谢谢
  • 我可能错了,但我认为你需要with-metaclojure.github.io/clojure/clojure.core-api.html#clojure.core/…
  • 你应该使用macroexpand-1的常规引用;有了它,您的调用变为(macroexpand-1 '(def- foo 12)),它返回(def foo 12) 的实际扩展。使用反引号,得到宏扩展的形式是(namespace/def- namespace/foo 12);正是这种形式扩展为(def namespace/foo 12),这是一个错误(传递给def 的“名称”符号可能不是命名空间限定的)。元数据问题如 kotarak 对the question linked to be Guillermo 的回答中所述。

标签: clojure


【解决方案1】:

因为clojure defmacro loses metadata,因为^是一个阅读器宏。

:privatesymbol metadata,所以它丢失了。

查看第一个链接上问题的答案以获得解决方案。

【讨论】:

  • 如果这是重复的,请不要写答案,而是留下评论或标记问题。在 3000 代表时,您将能够为此投票。
  • 确认,提出的问题不同,因此不完全重复,改进了答案以缩小此处提出的问题与原始链接中提供的解决方案之间的差距。
  • 这是真的,但与他实际看到的问题无关 - 以这种方式滥用元数据确实会导致他的 :private 丢失,但正如 Michal 在他的评论中所说,主要问题是他在他对macroexpand 的调用中使用`,而不是',因此在他的宏甚至看到名称之前添加了额外的namespace/ 限定符。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2015-03-22
  • 2016-08-19
  • 2018-03-23
  • 2017-07-03
  • 2022-11-15
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多