Clojure语言中的seq和list有什么区别?
(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
始终是一种抽象。Clojure Programming中指出,seq和列表之间的区别在于以下三个方面
1.获得序列的长度可能会很昂贵:
例如来自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可以是惰性的,而list不能。
(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
总是可以使用
cons
创建一个seq。在this post中查看更多信息,以了解cons
和conj
之间的区别。
关于list - 序列和列表之间的区别,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22416387/