Clojure 中的 seq 和 sequence 有什么区别?

What is the difference between seq and sequence in Clojure?

以下示例产生相同的输出。

(seq [1 2 3 4])
=> (1 2 3 4)

(sequence [1 2 3 4])
=> (1 2 3 4)

首先,他们以不同的方式对待空序列参数:

user> (seq nil)
nil
user> (seq ())
nil
user> (sequence ())
()
user> (sequence nil)
()

还有 sequence 有额外的特性可以在换能器上运行

截至文档:

clojure.core/sequence

[coll]

[xform coll]

[xform coll & colls]

Added in 1.0 Coerces coll to a (possibly empty) sequence, if it is not already one. Will not force a lazy seq. (sequence nil) yields (), When a transducer is supplied, returns a lazy sequence of applications of the transform to the items in coll(s), i.e. to the set of first items of each coll, followed by the set of second items in each coll, until any one of the colls is exhausted. Any remaining items in other colls are ignored. The transform should accept number-of-colls arguments

clojure.core/seq

[coll]

Added in 1.0 Returns a seq on the collection. If the collection is empty, returns nil. (seq nil) returns nil. seq also works on Strings, native Java arrays (of reference types) and any objects that implement Iterable. Note that seqs cache values, thus seq should not be used on any Iterable whose iterator repeatedly returns the same mutable object.

不同之处在于 sequence 总是 returns seq 即使集合为空(在那种情况下是一个空列表),而 seq returns nil 用于空集合。此外,sequence 可与 transducers 一起使用。

查看源代码:

user=> (source sequence)
(defn sequence
  "Coerces coll to a (possibly empty) sequence, if it is not already
  one. Will not force a lazy seq. (sequence nil) yields (), ..."
  ([coll]
     (if (seq? coll) coll
         (or (seq coll) ())))
  ...

所以调用 sequence 只有一个集合调用 seq 如果它还不是一个 seq 并且 returns 如果集合是一个空列表 nil.