2017-07-23 22 views
6

Tôi đã nhận thấy rằng nếu tôi def một mảng int và đặt một phần tử trong mảng bằng Long, thì không có khiếu nại. Tuy nhiên nếu tôi liên kết mảng int trong một khối let thiết lập một phần tử với một Long, sau đó một ngoại lệ IllegalArgument được ném. Ai đó có thể giúp tôi hiểu tại sao điều này?Tại sao các mảng int liên kết với 'def' chấp nhận các giá trị Long trong Clojure?

Mã bên dưới thể hiện sự khác biệt. Tôi đã thử nó trong cả Clojure 1.8 và phiên bản beta mới nhất 1.9 và có được những kết quả này.

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

Trả lời

9

Sự khác biệt này được gây ra bởi vì suy luận kiểu đang xảy ra trong let, nhưng không phải trong def. Bạn có thể xác minh điều này bằng cách sử dụng gợi ý kiểu để chuyển đổi các tình huống xung quanh:

(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 

Hoặc cách khác:

(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 

Điều này là do Clojure inlines calls to aset when possible, trong đó bao gồm tất cả những trường hợp này, nhưng các cuộc gọi inlined phương pháp tĩnh has many overloads .

+0

Đặt phần tử thành '-1' trông giống như một lỗi đối với tôi: bạn đang âm thầm nhận * bỏ chọn * số học. – Thumbnail

+0

@Thumbnail Tôi đồng ý; nó có vẻ giống như một lỗi dọc theo các dòng giống như [CLJ-1142] (https://dev.clojure.org/jira/browse/CLJ-1142). –

Các vấn đề liên quan