クロージャ:
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
何が起こっているかは理解できますが、これは別の方法で機能する必要がありますか?
ドキュメント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
、新しい要素を先頭に、既存のリストを末尾に持つ新しいリストを返します)。
リストとベクトルでは conj の動作が異なることがわかります。
conj は、追加された項目をリストの先頭とベクトルの末尾に配置します。
Clojure API conjも参照することをお勧めします
これにはいくつかの良い例があります。ClojureDocs 全体には、ほとんどの Clojure コマンドの非常に優れた例がいくつかあります。