Clojure的:
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
我明白发生了什么,但这应该有何不同?
答案 0 :(得分:20)
conj
的文档(来自clojure.org):
缀[OIN]。返回带有xs的新集合 '添加'。 (conj nil item)返回(item)。 '添加'可能 根据具体类型发生在不同的“地方”。
将“添加”元素添加到向量的末尾更有效,而在列表的开头执行此操作会更有效。 conj
使用对您提供的数据结构最有效的任何内容。
在您提供的示例中,'(1 2 3)
和(seq [1 2 3])
都实现了ISeq
(请参阅documentation for seq?
),而[1 2 3]
则没有。{/ p>
Clojure的conj
最终调用cons
方法(不要与cons
函数混淆 - 这个方法是内部的clojure代码)在底层数据结构上;对于向量(PersistentVector
),cons
将元素添加到结尾,而对于列表,它们被添加到前面(cons
方法为PersistentList
s返回一个新列表以新元素为首,将现有列表作为尾部。
答案 1 :(得分:6)
你会看到,conj与列表和向量的工作方式不同。
conj将添加的项放在列表的前面和向量的末尾。
我还建议查看Clojure API conj
有一些很好的例子。对于大多数Clojure命令,ClojureDocs总体上有一些很好的例子。