2017-07-23 69 views
6

Zauważyłem, że jeśli I def tablica int i ustawić element w tablicy za pomocą Long, to nie ma żadnych skarg. Jednak jeśli zwiążę tablicę int w zestawie bloków let, zostanie zgłoszony element z długim, a następnie wyjątkiem IllegalArgument. Czy ktoś mógłby mi pomóc zrozumieć, dlaczego tak jest?Dlaczego tablice int powiązane z "def" akceptują Długie wartości w Clojure?

Poniższy kod ilustruje rozbieżność. Próbowałem go zarówno w Clojure 1.8, jak i najnowszej wersji beta wersji 1.9 i otrzymałem te wyniki.

(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: 

Odpowiedz

9

Ta rozbieżność jest spowodowana bo typ wnioskowanie zachodzi w let, ale nie w def. Można to sprawdzić za pomocą wskazówek typu przełączyć sytuację wokół:

(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 

Lub alternatywnie:

(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 

To dlatego Clojure inlines calls to aset when possible, która zawiera wszystkie te przypadki, ale wywołanie inlined metoda statyczna has many overloads .

+0

Ustawienie elementu na "-1" wygląda mi na błąd: po cichu otrzymujesz * niezaznaczoną * arytmetyczną. – Thumbnail

+0

@Thumbnail Zgadzam się; wygląda na błąd podobny do [CLJ-1142] (https://dev.clojure.org/jira/browse/CLJ-1142). –