Clojure 类型转换不会发生
Clojure type conversion doesn't take place
我有以下函数可以给我一个散列图:
(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 和其他值)都默认为双精度类型。请注意,如果您强制将地图的键设置为浮动,那么即使地图的键超过 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"
我的猜测是,除了在 return 成功查找时发生小地图意外之外,这里的一切都按设计工作。
我相信使用小地图 get 确实找到查找匹配项 (float 1) 的原因可能是因为小地图的实现是作为一个 ArrayMap,其中查找键顺序与一个中的所有键进行比较使用 clojure.core/=(或其 Java 等价物)和:
的数组
user=> (= (float 1) (double 1))
true
所以,简而言之 - 地图中的键是双精度而不是浮点数。
(get (build-quarter-note-group 60) (double 1))
=> "cis'"
我有以下函数可以给我一个散列图:
(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 和其他值)都默认为双精度类型。请注意,如果您强制将地图的键设置为浮动,那么即使地图的键超过 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"
我的猜测是,除了在 return 成功查找时发生小地图意外之外,这里的一切都按设计工作。
我相信使用小地图 get 确实找到查找匹配项 (float 1) 的原因可能是因为小地图的实现是作为一个 ArrayMap,其中查找键顺序与一个中的所有键进行比较使用 clojure.core/=(或其 Java 等价物)和:
的数组user=> (= (float 1) (double 1))
true
所以,简而言之 - 地图中的键是双精度而不是浮点数。
(get (build-quarter-note-group 60) (double 1))
=> "cis'"