Clojure 元数据在某些形式上丢失
Clojure metadata lost on certain forms
我对以下表达式的行为差异感到困惑:
(pr (meta ^{:a 0} (list 1 2))) ;; prints nil returns nil
(pr (meta ^{:a 0} '(1 2)));; prints {:line 110, :column 20} returns nil
(pr (meta ^{:a 0} (range 1 3))) ;; prints nil returns nil
(pr (meta ^{:a 0} [1 2])) ;; prints {:a 0} returns nil
这是使用 clojure 1.8.0。我欢迎解释为什么结果不同。
Reader 元数据附加到 reader returns 的形式。在每种情况下,meta
都以该形式在运行时求值的任何值来调用。两者之间没有必要link
如果您需要在运行时将元数据附加到一个值,您可以使用 with-meta
来完成。
让我们看看在问题中列出的每种情况下会发生什么:
(pr (meta ^{:a 0} (list 1 2)))
Reader 元数据附加到列表结构 (list 1 2)
,但 meta
不是应用于此列表结构,而是应用于它在运行时计算的值,这将是新分配的两个项目的列表,没有附加元数据。
(pr (meta ^{:a 0} '(1 2)))
Reader 元数据附加到列表结构 (quote (1 2))
(单引号字符是 reader shorthand for (quote …)
),但是 meta
不应用于此列表结构,而是应用于它在运行时计算的值,即 reader 在读取此表达式时创建的 (1 2)
列表结构。这带有 {:line … :column …}
元数据,因为 Clojure reader 将其附加到某些类型的表单以用于错误消息等。
(pr (meta ^{:a 0} (range 1 3)))
同上第一种情况
(pr (meta ^{:a 0} [1 2]))
这与 '(1 2)
情况非常相似,但关键区别在于,如果非空列表不被视为 function/macro 调用,则需要引用非空列表,而向量则不需要,因此 reader 元数据实际上附加到感兴趣的文字 – 向量 – 本身。
这也适用于列表:
(pr (meta ' ^{:a 0} (1 2)))
^ note the quote comes before the metadata
;; prints {:line 1, :column 14, :a 0}
注意。显式 reader 元数据映射已合并到 reader 自行添加的 {:line … :column …}
映射中。
我对以下表达式的行为差异感到困惑:
(pr (meta ^{:a 0} (list 1 2))) ;; prints nil returns nil
(pr (meta ^{:a 0} '(1 2)));; prints {:line 110, :column 20} returns nil
(pr (meta ^{:a 0} (range 1 3))) ;; prints nil returns nil
(pr (meta ^{:a 0} [1 2])) ;; prints {:a 0} returns nil
这是使用 clojure 1.8.0。我欢迎解释为什么结果不同。
Reader 元数据附加到 reader returns 的形式。在每种情况下,meta
都以该形式在运行时求值的任何值来调用。两者之间没有必要link
如果您需要在运行时将元数据附加到一个值,您可以使用 with-meta
来完成。
让我们看看在问题中列出的每种情况下会发生什么:
(pr (meta ^{:a 0} (list 1 2)))
Reader 元数据附加到列表结构
(list 1 2)
,但meta
不是应用于此列表结构,而是应用于它在运行时计算的值,这将是新分配的两个项目的列表,没有附加元数据。(pr (meta ^{:a 0} '(1 2)))
Reader 元数据附加到列表结构
(quote (1 2))
(单引号字符是 reader shorthand for(quote …)
),但是meta
不应用于此列表结构,而是应用于它在运行时计算的值,即 reader 在读取此表达式时创建的(1 2)
列表结构。这带有{:line … :column …}
元数据,因为 Clojure reader 将其附加到某些类型的表单以用于错误消息等。(pr (meta ^{:a 0} (range 1 3)))
同上第一种情况
(pr (meta ^{:a 0} [1 2]))
这与
'(1 2)
情况非常相似,但关键区别在于,如果非空列表不被视为 function/macro 调用,则需要引用非空列表,而向量则不需要,因此 reader 元数据实际上附加到感兴趣的文字 – 向量 – 本身。这也适用于列表:
(pr (meta ' ^{:a 0} (1 2))) ^ note the quote comes before the metadata ;; prints {:line 1, :column 14, :a 0}
注意。显式 reader 元数据映射已合并到 reader 自行添加的
{:line … :column …}
映射中。