这是一个关于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
来确保集合是向量/集合,因为将conj
应用到nil
会创建一个列表,而我个人几乎从不使用列表。
- 必须对所有传入系统的集合边界运行
not-empty
。
您怎么看?