gpt4 book ai didi

collections - Clojure:cons (seq) 与 conj (list)

转载 作者:行者123 更新时间:2023-12-03 04:54:16 25 4
gpt4 key购买 nike

我知道 cons 返回一个 seq,conj 返回一个集合。我还知道 conj 将项目“添加”到集合的最佳末尾,而 cons 总是将项目“添加”到前面。这个例子说明了这两点:

user=> (conj [1 2 3] 4) ; returns a collection
[1 2 3 4]
user=> (cons 4 [1 2 3]) ; returns a seq
(4 1 2 3)

对于向量、 map 和集合,这些差异对我来说很有意义。然而,对于列表来说,它们似乎是相同的。

user=> (conj (list 3 2 1) 4) ; returns a list
(4 3 2 1)
user=> (cons 4 (list 3 2 1)) ; returns a seq
(4 3 2 1)

是否有任何使用列表的示例,其中 conjcons 表现出不同的行为,或者它们真的可以互换吗?换句话说,是否有一个列表和 seq 不能等效使用的示例?

最佳答案

一个区别是 conj 接受任意数量的参数插入到集合中,而 cons 仅接受一个:

(conj '(1 2 3) 4 5 6)
; => (6 5 4 1 2 3)

(cons 4 5 6 '(1 2 3))
; => IllegalArgumentException due to wrong arity

另一个区别在于返回值的类别:

(class (conj '(1 2 3) 4))
; => clojure.lang.PersistentList

(class (cons 4 '(1 2 3))
; => clojure.lang.Cons

请注意,这些并不是真正可以互换的;特别是, clojure.lang.Cons 没有实现 clojure.lang.Counted,因此对其进行 count 不再是恒定时间操作(在这种情况下,它可能会减少到 1 + 3 —— 1 来自对第一个元素的线性遍历,3 来自 (next (cons 4 '(1 2 3))PersistentList,因此计数)。

我相信,这些名称背后的意图是,cons 表示 cons(truct a seq)1,而 conj 表示conj(将一个项目添加到集合中)。由 cons 构造的 seq 从作为其第一个参数传递的元素开始,并具有 next/restseq 应用到第二个参数所产生的结果部分;如上所示,整个内容属于 clojure.lang.Cons 类。相反,conj 始终返回与传递给它的集合类型大致相同的集合。 (粗略地说,因为 PersistentArrayMap 一旦超过 9 个条目,就会变成 PersistentHashMap。)

<小时/>

1 传统上,在 Lisp 世界中,cons cons(tructs apair),因此 Clojure 背离了 Lisp 传统,拥有它的 cons 函数构造一个没有传统 cdr 的 seq。 cons 的一般用法是指“构造某种类型或其他类型的记录以将多个值保存在一起”,目前在编程语言及其实现的研究中普遍存在;这就是提到“避免欺骗”时的含义。

关于collections - Clojure:cons (seq) 与 conj (list),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3008411/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com