2024年Clojure状态调查! 中分享你的想法。

欢迎!请参阅 关于 页面,了解更多关于如何使用本网站的信息。

+6
Clojure

user=> (case -1 -1 true false) true user=> (case [-1] [-1] true false) true user=> (case (int -1) -1 true false) true user=> (case [(int 1)] [1] true false) true user=> (case [(int -1)] [-1] true false) false

最后一个案例应该返回true,像其他案例一样

引发这个问题的真实例子

(case [">" (compare 2 3)] [">" -1] true false) ;; false?

解释:这是由于case在哈希比较时使用了hashCode而不是hashEq(当没有用向量包装时,比较是直接的),并且负整数和负长整型的哈希不同,而正整数哈希相同。
建议:使case使用hasheq而不是hashCode

补丁:0001-switch-to-hasheq-for-case.patch

昨天刚刚遇到这个问题,花了一些时间才弄清楚这是根本问题。 那段代码中是(-1 :x)而不是[-1 ...],但是得到了相同的结果 - 错误的子句被选择了。 将输入值强制转换为长整数选择了正确的子句(版本1.11.1)。

很高兴看到这个问题被修复。

2 答案

0
by

评论由:bronsa 发布

补丁是一个简单的查找和替换,除了diff中的第30行相当棘手:我相信在那里的使用 h 上之前的实现中存在一个bug,这个bug从未暴露出来,因为正整数的hashCode是等幂的。但是,由于hashEq不是双哈希,会导致碰撞节点永远不匹配。

0
by
参考:https://clojure.atlassian.net/browse/CLJ-2275 (由 alex+import 报告)
...