seq和列表之间的差异

alb*_*hin 6 list clojure sequence seq

Clojure语言中seqs和list之间的区别是什么?

(list [1 2 3]) => ([1 2 3])
(seq [1 2 3]) => ([1 2 3])
Run Code Online (Sandbox Code Playgroud)

这两种形式似乎被评估为相同的结果.

alb*_*hin 16

首先,它们似乎是相同的,但它们不是:

(class (list [1 2 3])) => clojure.lang.PersistentList
(class (seq [1 2 3])) => clojure.lang.PersistentVector$ChunkedSeq
Run Code Online (Sandbox Code Playgroud)

list通常是一种实现,而seq始终是一种抽象.

seqs和list之间的区别在于以下三个方面,正如Clojure Programming中所指出的那样

1.获得seq的长度可以是costy:

例如来自Clojure Programming

(let [s (range 1e6)]
  (time (count s))) => 1000000
; "Elapsed time: 147.661 msecs"

(let [s (apply list (range 1e6))]
  (time (count s))) => 1000000
; "Elapsed time: 0.03 msecs
Run Code Online (Sandbox Code Playgroud)

因为列表总是保存其自身长度的记录,所以计算列表的操作花费了恒定的时间.然而,seq需要遍历自己来检索它count.

2. seqs可以是懒惰的,而列表则不能.

 (class (range)) => clojure.lang.LazySeq
 (class (apply list (range))) ;cannot be evaluated
 ; "java.lang.OutOfMemoryError: GC overhead limit exceeded"
Run Code Online (Sandbox Code Playgroud)

3. seqs可以是无限的,因此是不可数的,而列表总是可数的.

此外,列表是他们自己的seqs(实现细节):

(class (seq '(1 2 3))) => clojure.lang.PersistentList
Run Code Online (Sandbox Code Playgroud)

人们总是可以使用创建seq cons.有关和之间的差异,请查看此帖子中的更多信息.consconj


Ale*_*ler 9

列表是作为链表实现的集合数据结构.(其他核心集合数据结构是向量,映射和集合.)

序列是一种列表抽象,可以应用于多种数据.将序列视为一个逻辑视图,可以让您按顺序遍历某些元素.

列表是具体类型与抽象匹配的情况,因此列表实际上是一个序列.但是,有许多序列不是列表,而是一些其他实现作为另一个数据结构的视图(如clojure.lang.PersistentVector $ ChunkedSeq).

如果仔细观察,核心库中的函数将分为集合函数(将集合作为第一个参数并返回相同类型的集合)和序列函数(将"seqable"事物作为最后一个参数,将其转换为序列,执行其功能,并返回序列).实施例的收集功能是conj,assoc,count,get,等.示例序列功能是map,reduce,filter,等.事实上,对序列,不特定集合类型的大部分芯库作品.

序列是将所有Clojure数据结构与核心库中的所有FP函数结合在一起的抽象.这种统一是Clojure代码的简洁性和可重用性的基础.