为什么用'def'绑定的int数组在Clojure中接受Long值?
问题描述:
我注意到如果我使用def
一个int数组并在Long中设置了一个数组中的元素,那么就没有抱怨。但是,如果我将int数组绑定到let
块中,则使用Long设置一个元素,然后抛出IllegalArgument异常。有人能帮我理解这是为什么吗?为什么用'def'绑定的int数组在Clojure中接受Long值?
下面的代码显示了差异。我在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,其中包括所有的这些情况,但内联静态方法调用has many overloads 。
将元素设置为'-1'对我来说看起来像一个错误:你正默默地* unchecked *算术。 – Thumbnail
@Thumbnail我同意;它看起来像一个与[CLJ-1142](https://dev.clojure.org/jira/browse/CLJ-1142)相同的错误。 –