8

Clojure 元仅在函数注意这样做并且 Clojure 核心函数不会全局保留元时才会保留。我听说过的一般经验法则是,conj、assoc 等集合函数应该保留元数据,但 map、filter、take 等序列函数不保留元数据。

是否有一个列表列出了哪些功能可以保留元数据?

4

1 回答 1

5

这都是关于类型的。序列函数就像调用seq参数一样,因此并不总是返回相同类型的对象。集合函数和特定类型的函数不会调用 seq 并返回与给定它们的类型相同的对象。这有点让他们产生返回相同对象的错觉(这可能是这种行为的原因),即使事实并非如此。我们可以说经验法则是函数在保留类型时保留元数据。

user> (meta (seq (with-meta (list 1) {:a 1})))
{:a 1}
user> (meta (seq (with-meta (vector 1) {:a 1})))
nil

请务必注意何时涉及懒惰:

user> (type (list 1))
clojure.lang.PersistentList
user> (type (map identity (list 1)))
clojure.lang.LazySeq
user> (meta (seq (with-meta (map identity (list 1)) {:a 1})))
nil

有关在集合中保留元数据的函数列表,请参阅数据结构页面。不保留元数据的位于序列页面下,但它们返回相同类型的对象时除外。

由于添加了惰性和分块序列,因此我不太确定细节,但您可以查看类中的cons,seqseqFrom方法RT。不保留元数据的功能通过这些方法。而集合函数最终使用特定于其类型的方法。

于 2011-01-13T04:45:24.923 回答