我有以下函数,它给我一个哈希映射:
(build-quarter-note-group 60)
;;=> {0.0 "c'", 2.0 "cisis'", -2.0 "ceses'", 0.5 "cih'", -0.5 "ceh'", 1.0 "cis'", -1.0 "ces'", 1.5 "cisih'", -1.5 "ceseh'"}
然后我通过get
ing另一个函数中的地图中的键来获取值。
(defn keynum->name
([keynum] (->> 0.0 (get (build-quarter-note-group keynum))))
([keynum transposition] (->> (float transposition) (get (build-quarter-note-group keynum)))))
由于密钥都是keynum->name
函数中的浮点数,我确实尝试进行类型强制,但是这发生了:
(keynum->name 60 1) ;;=> nil
(get (build-quarter-note-group 60) (float 1)) ;;=> nil
(float 1)
的结果会怎样?
引用给the issue I opened in the Clojure Jira的答案:
我相信在最多8个键的地图中查找浮点数这一事实是实施的意外。
它因较大的映射和散列集而失败的原因是(double 1.0)和(float 1.0)的散列值不同。
user=> (hash (float 1.0))
1065353216
user=> (hash 1.0)
1072693248
在您的示例中,所有值(如1.0和其他值)都默认为double类型。请注意,如果强制映射的键是浮动的,那么即使映射具有8个以上的键,查找也会成功:
user=> (get {(float 1.0) "a" 2.0 "b" 3.0 "c" 4.0 "d" 5.0 "e" 6.0 "f" 7.0 "g" 8.0 "h" 1 "i"} (float 1))
"a"
我的猜测是,除了用小地图获得的事故恰好返回成功的查找,这里的一切都按设计工作。
我相信使用小地图确实找到匹配的原因(浮点1)可能是因为小地图的实现是一个ArrayMap,其中查找键被顺序地与使用clojure.core的数组中的所有键进行比较/ =(或其Java等价物),和:
user=> (= (float 1) (double 1))
true
所以,简而言之 - 地图中的键是双精度而不是浮点数。
(get (build-quarter-note-group 60) (double 1))
=> "cis'"