2017-07-23 23 views
6

我注意到如果我使用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: 

回答

9

这种差异是因为类型推断在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

+0

将元素设置为'-1'对我来说看起来像一个错误:你正默默地* unchecked *算术。 – Thumbnail

+0

@Thumbnail我同意;它看起来像一个与[CLJ-1142](https://dev.clojure.org/jira/browse/CLJ-1142)相同的错误。 –

相关问题