我注意到,如果我 def
一个 int 数组并用 Long 设置数组中的一个元素,那么就不会出现任何提示。但是,如果我在 let
block 中绑定(bind) int 数组并设置一个具有 Long 的元素,则会引发 IllegalArgument 异常。有人可以帮我理解这是为什么吗?
下面的代码演示了这种差异。我在 Clojure 1.8 和最新的 beta 版本 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 ,其中包括所有这些情况,但内联静态方法调用 has many overloads .
关于arrays - 为什么与 'def' 绑定(bind)的 int 数组在 Clojure 中接受 Long 值?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45270009/