这是一个关于3种不同Clojure方面的交集的问题
- 集合函数将
nil
视为空集合。像filter
、map
甚至assoc
这样的函数愉快地接受nil
作为coll。
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
。
您怎么看?