empty?
的文档字符串表示"请使用成语(seq x)而不是(not(empty?x))"。 MisterMetaphor指出在seq
中使用if-let
时,使用(if-let [s (seq might-be-empty)]
(fn-for-non-empty-seq s)
(fn-for-empty-seq))
作为谓词是有意义的:
seq
但是,我真的应该使用seq
来测试一般的非空虚吗? user=> (class (lazy-seq '(1 2 3)))
clojure.lang.LazySeq
user=> (class (seq (lazy-seq '(1 2 3))))
clojure.lang.PersistentList
user=> (class (map inc [1 2 3]))
clojure.lang.LazySeq
user=> (class (seq (map inc [1 2 3])))
clojure.lang.ChunkedCons
可以将其参数转换为其他形式。例如:
not-empty
如果只是想测试非空虚,并且不需要新的绑定,或者在绑定之前我不需要转换,这似乎是浪费周期。在这种情况下,nil
不是更好的选择吗?如果参数为空,则返回(if (not-empty [])
"more to do"
"all done")
,如果非空,则返回其参数。
{{1}}
答案 0 :(得分:16)
首先,查看empty?
的定义:
(defn empty?
"Returns true if coll has no items - same as (not (seq coll)).
Please use the idiom (seq x) rather than (not (empty? x))"
{:added "1.0"
:static true}
[coll] (not (seq coll)))
所以empty?
是 (not (seq coll))
。这就是为什么不鼓励补充empty?
,因为你在seq
上做了双重否定。
现在看not-empty
(defn not-empty
"If coll is empty, returns nil, else coll"
{:added "1.0"
:static true}
[coll] (when (seq coll) coll))
令人惊讶的是,它也使用seq
作为非空虚的测试。如果类型很重要,not-empty
有用 - nth
对向量的表现,conj
行为等等 - 因为它确实将非空的colls返回为是。仅用作谓词,它只包装seq
。
不要担心seq
会变得笨手笨脚。它只是返回一个迭代器。它实际上并不转换整个数据结构。