这是一个关于3个不同的Clojure方面的交集的问题
- 集合函数将
nil
视为空集合。如filter
、map
甚至assoc
等函数都乐于接受nil
作为集合。
if
及其相关宏(如when
、and
、or
等)将nil
视为非真值。
empty?
将其输入强制转换为seq
,这使得不必要的内存分配变得多余。使用seq
而不是(not (empty? xs))
来检查非空是常见的惯例。这通常是一个混淆的来源,因为(not (empty? xs))
的意图似乎比seq
更清晰。
话虽如此,我认为在应用中明确地将每个空集合表示为nil
可能是有用的,因为这样
(let [xs (get-non-empty-coll-or-nil)]
(if xs
(do-stuff-with xs)
(do-nothing)))
...比这样更高效、更清晰
(let [xs (get-possibly-empty-coll)]
(if (seq xs)
(do-stuff-with xs)
(do-nothing)))
这种方法的两个缺点是
- 必须使用
(fnil conj [])
或(fnil conj #{})
而不是conj
来确保集合是向量或集合,因为将元素添加到nil
将创建一个列表,而我个人几乎从未使用过列表。
- 必须对所有传入集合的边界进行
not-empty
检查。
你有什么看法?