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

コレクションでメタを保持する関数のリストについては、データ構造のページを参照してください。メタを保持しないものは、同じタイプのオブジェクトを返す場合を除いて、シーケンスページの下にあります。

ボンネットの下では、遅延とチャンク シーケンスが追加されているため、詳細についてはよくわかりませんが、クラスのconsseqおよびseqFromメソッドを見ることができます。RTメタデータを保存しない関数は、これらのメソッドを通過します。コレクション関数は、その型に固有のメソッドを使用することになります。

于 2011-01-13T04:45:24.923 に答える