我遇到了一些有趣的 sorted-set 行为。具体来说,对于常规 set 的用户协议是在元素不存在时返回 nil。然而,对于 sorted-set,如果比较器没有优雅地处理类型,调用会抛出异常。这种行为的原因是可以理解的(比较器需要能够合理地比较元素),但在“不包含”的情况下,由于我们知道如果元素的类型不能默认比较,则该元素就不存在于集合中,因此接口有些令人困惑。
换句话说,我认为我提出的是,对于使用默认比较器的有序集合,一个合理的默认行为是当类型无法比较时应返回 nil,而不是 throw,以便允许 nil 代用。
例如,在将形式传递给关键字函数(:foobar form)
时遇到了这种情况,该函数允许很多其他集合进行 nil 代用。这里有一小段示例代码:
`
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)在用户/评估246355(from-init59552761865518221.clj:8123)。
类型 java.lang.String 无法转换为类型 clojure.lang.Keyword(java.lang.String 在模块 java.base 中,clojure.lang.Keyword 在未命名的模块中)。
`
我认为我处理这种情况的选项是 try/catch 或编写自定义比较器,两者都有些奇特 :)
我可能忽视了一些东西,但还是觉得很有趣 :)