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
我了解发生了什么,但这应该以不同的方式工作吗?
文档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
返回一个新列表,其中新元素作为其头部,现有列表作为其尾部)。
如果您查看Clojure 数据结构
您会看到 conj 与列表和向量的工作方式不同。
conj 将添加的项目放在列表的前面和向量的末尾。
我还建议查看Clojure API conj
其中有一些很好的例子。ClojureDocs 总体上为大多数 Clojure 命令提供了一些非常好的示例。