2017-07-23 5 views
6

J'ai remarqué que si je def un tableau int et définir un élément dans le tableau avec un long, alors il n'y a pas de plaintes. Toutefois, si je lie le tableau int dans un bloc let, définissez un élément avec un long, puis une exception IllegalArgument est levée. Quelqu'un pourrait-il m'aider à comprendre pourquoi?Pourquoi les tableaux int liés avec 'def' acceptent-ils les valeurs longues dans Clojure?

Le code ci-dessous illustre la divergence. Je l'ai essayé à la fois dans Clojure 1.8 et la dernière version bêta de 1.9 et j'ai obtenu ces résultats.

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

Répondre

9

Cet écart est dû au fait que l'inférence de type se produit dans le let, mais pas dans le def. Vous pouvez vérifier cela en utilisant des notes de type pour changer la situation autour de:

(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 

Ou encore:

(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 

En effet, Clojure inlines calls to aset when possible, qui comprend tous ces cas, mais la méthode statique inline appel has many overloads .

+0

La définition de l'élément '-1' me semble être un bug: vous êtes en mode arithmétique * sans aucun contrôle. – Thumbnail

+0

@Thumbnail Je suis d'accord; cela ressemble à un bug dans le même sens que [CLJ-1142] (https://dev.clojure.org/jira/browse/CLJ-1142). –