sorted-map会在失败的键查找时抛出异常

时间:2016-05-24 10:13:22

标签: exception dictionary clojure dynamic-typing

user=> (def m (sorted-map 1 2))
#'user/m
user=> (map? m)
true
user=> (get m :type)
ClassCastException java.lang.Long cannot be cast to clojure.lang.Keyword
  clojure.lang.Keyword.compareTo (Keyword.java:114)

sorted-map似乎选择了一个数字比较函数,该函数不会与关键字进行比较。

理由很好,"这个东西支持IPersistentMap。所以,我可以在其上调用get来查明它是否是我所知道的一种地图,而不会有抛出异常的风险。" get的文档字符串表示"如果键不存在,则返回映射到key,not-found或nil的值。"

在关键查找错误时抛出异常?更重要的是,是否有一种安全,标准的方法来检查任意对象是否属于给定的类型" (由与其:type键关联的值定义)?

2 个答案:

答案 0 :(得分:2)

sorted-map的密钥在某种程度上应具有可比性似乎是合理的,1:type的情况并非如此,这是异常的原因。< / p>

话虽如此,我说你应该能够使用任何类型的密钥查询地图,如果地图中提供的密钥和密钥不具有可比性,则会获得nil

您可以通过提供所需类型检查的sorted-map-by提供自己的比较器来解决问题。

答案 1 :(得分:0)

这是一个发人深省的问题,我很高兴你问过它。在思考之后,我倾向于期望与其他答案中提到的相同 - 我可能希望返回nil,但也许Rich有这样做的哲学原因。

至于问题的最后部分:您可以使用type。如果要测试已知类型,也可以使用instance?。我猜诀窍是类型(几乎总是我相信)将成为底层Java类

user=> (type foo)
clojure.lang.PersistentTreeMap

user=> (instance? clojure.lang.PersistentTreeMap foo)
true

编辑: 在下面的讨论中,我在这里添加了一些额外的示例代码(比评论更容易阅读)。这将允许任意元数据附加到数据结构:

user=> (def foo (sorted-map 1 2))
#'user/foo
user=> (def foo-enhanced (with-meta foo {:type :integer-keys}))
#'user/foo-enhanced
user=> foo-enhanced
{1 2}
user=> (meta foo-enhanced)
{:type :integer-keys}