我遇到了一些有趣的sorted-set
行为。例如,对于正常set
的用户协议是当元素不存在时返回nil
。然而,与sorted-set
不同,如果比较器不能优雅地处理类型,调用将抛出异常。这个原因是有意义的(比较器要求能够健康地比较元素),但在“无成员”情况下,接口有点令人困惑,因为我们知道如果元素的类型不能通过默认比较,那么该元素就不存在于集合中。
换句话说,我猜测我正在提议,对于使用默认比较器的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)在user/eval246355(form-init59552761865518221.clj:8123)。
类java.lang.String无法转换为类clojure.lang.Keyword(java.lang.String位于模块java.base的加载器'bootstrap'中;clojure.lang.Keyword位于未命名的模块的加载器'app'中)
`
我认为我处理此问题的选项是尝试/捕获或者编写一个自定义比较器,两者都感觉有点奇怪 :)
我可能遗漏了某些东西,但是仍然觉得很有趣 :)