10

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

我了解发生了什么,但这应该以不同的方式工作吗?

4

2 回答 2

20

文档conj(来自clojure.org):

结合[oin]。返回一个带有 xs 'add' 的新集合。(conj nil item) 返回 (item)。根据具体类型,“添加”可能发生在不同的“地方”。

将元素“添加”到向量的末尾更有效,而在列表的开头这样做更有效。conj使用对您提供的数据结构最有效的任何东西。

在您提供的示例中,'(1 2 3)(seq [1 2 3])实现了ISeq(请参阅文档seq?),而[1 2 3]没有实现。

Clojureconj最终在底层数据结构上调用cons方法(不要与函数混淆——该方法是内部 clojure 代码);cons对于向量 ( PersistentVector),cons将元素添加到末尾,而对于列表,它们将添加到前面(s 的cons方法PersistentList返回一个新列表,其中新元素作为其头部,现有列表作为其尾部)。

于 2011-09-15T22:50:47.677 回答
6

如果您查看Clojure 数据结构

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

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

我还建议查看Clojure API conj

其中有一些很好的例子。ClojureDocs 总体上为大多数 Clojure 命令提供了一些非常好的示例。

于 2011-09-15T22:50:05.717 回答