Clojure 元仅在函数注意这样做并且 Clojure 核心函数不会全局保留元时才会保留。我听说过的一般经验法则是,conj、assoc 等集合函数应该保留元数据,但 map、filter、take 等序列函数不保留元数据。
是否有一个列表列出了哪些功能可以保留元数据?
这都是关于类型的。序列函数就像调用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
,seq
和seqFrom
方法RT
。不保留元数据的功能通过这些方法。而集合函数最终使用特定于其类型的方法。