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中所指出的那样
例如来自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.
(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)
此外,列表是他们自己的seqs(实现细节):
(class (seq '(1 2 3))) => clojure.lang.PersistentList
Run Code Online (Sandbox Code Playgroud)
人们总是可以使用创建seq cons.有关和之间的差异,请查看此帖子中的更多信息.consconj
列表是作为链表实现的集合数据结构.(其他核心集合数据结构是向量,映射和集合.)
序列是一种列表抽象,可以应用于多种数据.将序列视为一个逻辑视图,可以让您按顺序遍历某些元素.
列表是具体类型与抽象匹配的情况,因此列表实际上是一个序列.但是,有许多序列不是列表,而是一些其他实现作为另一个数据结构的视图(如clojure.lang.PersistentVector $ ChunkedSeq).
如果仔细观察,核心库中的函数将分为集合函数(将集合作为第一个参数并返回相同类型的集合)和序列函数(将"seqable"事物作为最后一个参数,将其转换为序列,执行其功能,并返回序列).实施例的收集功能是conj,assoc,count,get,等.示例序列功能是map,reduce,filter,等.事实上,对序列,不特定集合类型的大部分芯库作品.
序列是将所有Clojure数据结构与核心库中的所有FP函数结合在一起的抽象.这种统一是Clojure代码的简洁性和可重用性的基础.