最近在使用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)
执行错误(类转换异常)在 user/eval246355 (form-init59552761865518221.clj:8123)。
类 java.lang.String 无法转换到类 clojure.lang.Keyword (java.lang.String 位于模块 java.base 的加载器 'bootstrap' 中;clojure.lang.Keyword 位于未命名的模块的加载器 'app' 中)
`
我认为我处理这种情况的选择是 try/catch 或编写自定义比较器,但这两种方法似乎都有些糟糕 :)
我可能遗漏了某些东西,但仍然觉得这很有趣 :)