【问题标题】:What functions in Clojure core preserve meta?Clojure 核心中的哪些函数保留了元数据?
【发布时间】:2011-06-08 01:32:44
【问题描述】:

Clojure 元数据仅在函数谨慎执行且 Clojure 核心函数未全局保留元数据时才会保留。我听说的一般经验法则是,conj、assoc 等集合函数应该保留 meta,但 map、filter、take 等序列函数不保留 meta。

在某处有哪些功能可以保留元数据的列表吗?

【问题讨论】:

    标签: clojure meta


    【解决方案1】:

    这都是关于类型的。序列函数的行为就像他们在参数上调用 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
    

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

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

    【讨论】:

      猜你喜欢
      • 2011-03-08
      • 2014-07-30
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-11-18
      • 2023-03-18
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多