Clojure 语言中的 seq 和列表有什么区别?
(list [1 2 3]) => ([1 2 3])
(seq [1 2 3]) => ([1 2 3])
这两种形式似乎被评估为相同的结果。
首先,它们可能看起来相同,但实际上并非如此:
(class (list [1 2 3])) => clojure.lang.PersistentList
(class (seq [1 2 3])) => clojure.lang.PersistentVector$ChunkedSeq
list
通常是一个实现,而seq
始终是一个抽象。
seqs和lists的区别在于以下三个方面,如Clojure 编程 http://www.clojurebook.com/
1. 获取 seq 的长度可能会很昂贵:
例如从Clojure 编程
(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
因为列表总是保存其自身长度的记录,所以对列表进行计数的操作花费恒定的时间。然而,seq 需要遍历自身来检索它的count
.
2. seqs 可以是惰性的,而列表则不能。
(class (range)) => clojure.lang.LazySeq
(class (apply list (range))) ;cannot be evaluated
; "java.lang.OutOfMemoryError: GC overhead limit exceeded"
3. seq 可以是无限的,因此不可数,而列表总是可数的。
此外,列表是它们自己的 seq(实现细节):
(class (seq '(1 2 3))) => clojure.lang.PersistentList
人们总是可以使用以下命令创建一个 seqcons
。查看更多信息这个帖子 https://stackoverflow.com/questions/3008411/clojure-seq-cons-vs-list-conj对于之间的差异cons
and conj
.
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)