与Clojure序列不一致?

时间:2011-09-15 21:47:51

标签: clojure seq

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

我明白发生了什么,但这应该有何不同?

2 个答案:

答案 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)

如果你看Clojure Data Structures

你会看到,conj与列表和向量的工作方式不同。

conj将添加的项放在列表的前面和向量的末尾。

我还建议查看Clojure API conj

有一些很好的例子。对于大多数Clojure命令,ClojureDocs总体上有一些很好的例子。