为什么用 'def' 绑定的 int 数组接受 Clojure 中的 Long 值?
Why do int arrays bound with 'def' accept Long values in Clojure?
我注意到,如果我 def
一个 int 数组并在该数组中设置一个元素为 Long,则没有任何抱怨。但是,如果我在 let
块中绑定 int 数组并设置一个具有 Long 的元素,则会引发 IllegalArgument 异常。谁能帮我理解这是为什么?
下面的代码演示了差异。我在 Clojure 1.8 和最新的 1.9 测试版中都试过了,得到了这些结果。
(def a (int-array 10))
(aset a 0 Long/MAX_VALUE) ;; sets first element to -1
(let [b (int-array 10)]
(aset b 0 Long/MAX_VALUE)) ;; throws java.lang.IllegalArgumentException: Value out of range for int:
造成这种差异的原因是类型推断发生在 let
中,而不是发生在 def
中。您可以通过使用类型提示来切换情况来验证这一点:
(def ^"[I" a (int-array 10))
(aset a 0 Long/MAX_VALUE)
;; throws java.lang.IllegalArgumentException: Value out of range for int:
(let [^Object b (int-array 10)]
(aset b 0 Long/MAX_VALUE))
;; sets first element to -1
或者,或者:
(def a (int-array 10))
(aset ^"[I" a 0 Long/MAX_VALUE)
;; throws java.lang.IllegalArgumentException: Value out of range for int:
(let [b (int-array 10)]
(aset ^Object b 0 Long/MAX_VALUE))
;; sets first element to -1
这是因为Clojure inlines calls to aset
when possible, which includes all these cases, but the inlined static method call has many overloads.
我注意到,如果我 def
一个 int 数组并在该数组中设置一个元素为 Long,则没有任何抱怨。但是,如果我在 let
块中绑定 int 数组并设置一个具有 Long 的元素,则会引发 IllegalArgument 异常。谁能帮我理解这是为什么?
下面的代码演示了差异。我在 Clojure 1.8 和最新的 1.9 测试版中都试过了,得到了这些结果。
(def a (int-array 10))
(aset a 0 Long/MAX_VALUE) ;; sets first element to -1
(let [b (int-array 10)]
(aset b 0 Long/MAX_VALUE)) ;; throws java.lang.IllegalArgumentException: Value out of range for int:
造成这种差异的原因是类型推断发生在 let
中,而不是发生在 def
中。您可以通过使用类型提示来切换情况来验证这一点:
(def ^"[I" a (int-array 10))
(aset a 0 Long/MAX_VALUE)
;; throws java.lang.IllegalArgumentException: Value out of range for int:
(let [^Object b (int-array 10)]
(aset b 0 Long/MAX_VALUE))
;; sets first element to -1
或者,或者:
(def a (int-array 10))
(aset ^"[I" a 0 Long/MAX_VALUE)
;; throws java.lang.IllegalArgumentException: Value out of range for int:
(let [b (int-array 10)]
(aset ^Object b 0 Long/MAX_VALUE))
;; sets first element to -1
这是因为Clojure inlines calls to aset
when possible, which includes all these cases, but the inlined static method call has many overloads.