我遇到了一个关于 sorted-set
的有趣行为。具体来说,对于正常的 set
,当元素不存在时其合约是返回 nil
。然而,对于 sorted-set
,如果比较器不能优雅地处理类型,则调用会抛出异常。这个 原因 是合理的(比较器需要能够合理地比较元素),但由于我们知道如果元素类型无法通过默认方式比较,则该元素不存在于集合中,因此这种“不存在”的界面在某种程度上有些令人困惑。
换句话说,我认为我建议对于使用默认比较器的有序集合的合理默认行为应该是当类型无法比较时返回 nil
而不是抛出异常,以便允许 nil
-punning。
例如,当将形式传递给关键字函数 (:foobar form)
时遇到这种情况,它允许许多其他集合进行 nil-punning。以下是一个小片段
`
user> (def normal #{"0000"})
;; => #'user/normal
user> (def sorted-version (sorted-set "0000"))
;; => #'user/sorted-version
user> normal
;; => #{"0000"}
user> sorted-version
;; => #{"0000"}
user> (:foobar normal)
;; => nil
user> (:foobar sorted-version)
执行错误 (ClassCastException) 在用户/eval246355 (form-init59552761865518221.clj:8123)。
无法将 java.lang.String 转换为 clojure.lang.Keyword (java.lang.String 位于模块 java.base 中,clojure.lang.Keyword 位于未命名的模块中)
`
我认为我处理这种情况的选择是 try/catch 或编写自定义比较器,但两种方法似乎都有些奇怪 :)
我可能遗漏了某些内容,但仍然认为这很有趣 :)