10

クロージャ:

1:13 user=> (first (conj '(1 2 3) 4))
4
1:14 user=> (first (conj [1 2 3] 4))
1
; . . .
1:17 user=> (first (conj (seq [1 2 3]) 4))
4

何が起こっているかは理解できますが、これは別の方法で機能する必要がありますか?

4

2 に答える 2

20

ドキュメントconj( clojure.orgから):

conj[oin]。xs が「追加」された新しいコレクションを返します。(conj nil item) は (item) を返します。「追加」は、具体的なタイプに応じて異なる「場所」で発生する可能性があります。

ベクトルの末尾に要素を「追加」する方が効率的ですが、リストの先頭に追加する方が効率的です。conj指定したデータ構造に対して最も効率的なものを使用します。

あなたが与える例では'(1 2 3)(seq [1 2 3])両方が実装されていますISeqのドキュメントをseq?参照)が、そうではあり[1 2 3]ません。

Clojureconjは最終的に、基礎となるデータ構造consに対してメソッドを呼び出します (関数と混同しないでください。consこのメソッドは clojure の内部コードです)。ベクトル ( PersistentVector) の場合consは要素を末尾に追加し、リストの場合は先頭に追加します (s のconsメソッドはPersistentList、新しい要素を先頭に、既存のリストを末尾に持つ新しいリストを返します)。

于 2011-09-15T22:50:47.677 に答える
6

Clojure Data Structuresを見ると

リストとベクトルでは conj の動作が異なることがわかります。

conj は、追加された項目をリストの先頭とベクトルの末尾に配置します。

Clojure API conjも参照することをお勧めします

これにはいくつかの良い例があります。ClojureDocs 全体には、ほとんどの Clojure コマンドの非常に優れた例がいくつかあります。

于 2011-09-15T22:50:05.717 に答える