2017-07-23 25 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)相同的錯誤。 –

相關問題