2011-01-12 50 views
8

Clojure meta僅在一個函數需要注意時保留,而Clojure核心函數不能全局保留元。我聽說的一般經驗法則是像conj,assoc等集合函數應該保留元,但是像map,filter,take等序列函數並不保留元。Clojure核心中的哪些功能可以保存meta?

有什麼功能可以保存meta的列表嗎?

回答

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 

對於保留對收集的元功能的列表,請參閱data structures頁。那些不保留meta的頁面位於sequences頁面下,除了它們返回相同類型的對象時。

引擎蓋下我不是很肯定,因爲懶惰的細節和分塊序列已被添加,但你可以看看從RTconsseqseqFrom方法。不保留元數據的功能通過這些方法。雖然集合函數最終使用特定於其類型的方法。