2010-06-28 20 views
19

Tôi đang thử dùng Clojure 1.2, các trường cụ thể có thể thay đổi được hỗ trợ trong deftype theo số clojure.org documentation.Các trường có thể ẩn trong định dạng Clojure?

Nhưng tôi không thể thiết lập để hoạt động. Cú pháp để cập nhật một trường là gì? Hoặc chưa được triển khai chưa?

(definterface IPoint 
    (getX []) 
    (setX [v])) 

(deftype Point [x] 
    IPoint 
    (getX [this] x) 
    (setX [this v] (set! (.x this) v))) 

user=> (def p (Point. 10)) 
user=> (.getX p) 
10 
user=> (.setX p 20) 
ClassCastException: user.Point cannot be cast to compile__stub.user.Point 

Sử dụng ảnh chụp nhanh 1.2 từ vài ngày trước.

Trả lời

40

deftype Mặc định là vẫn có trường không thay đổi được; để ghi đè điều này, bạn cần phải chú thích tên của các trường có thể được thay đổi bằng siêu dữ liệu thích hợp. Ngoài ra, cú pháp cho set! của các trường mẫu là khác nhau. Ví dụ về triển khai thực hiện công việc trên:

(deftype Point [^{:volatile-mutable true} x] 
    IPoint 
    (getX [_] x) 
    (setX [this v] (set! x v))) 

Còn có :unsynchronized-mutable. Sự khác biệt là những cái tên sẽ gợi ý cho một nhà phát triển Java có kinh nghiệm. ;-) Lưu ý rằng việc cung cấp hoặc chú thích có tác dụng bổ sung làm cho lĩnh vực tư nhân, do đó truy cập trực tiếp lĩnh vực không còn có thể:

(.getX (Point. 10)) ; still works 
(.x (Point. 10)) ; with annotations -- IllegalArgumentException, works without 

Ngoài ra, 1,2 sẽ có khả năng hỗ trợ các cú pháp ^:volatile-mutable x như viết tắt cho ^{:volatile-mutable true} x (điều này đã có sẵn trên một số nhánh số mới).

Cả hai tùy chọn đều được đề cập trong (doc deftype); phần có liên quan sau - hãy chú ý đến lời khuyên!

Fields có thể đủ điều kiện với siêu dữ liệu: dễ bay hơi-có thể thay đổi đúng hay: unsynchronized-mutable đúng, tại thời điểm đó (thiết lập vùng xa Aval!) Sẽ được hỗ trợ trong phương pháp cơ quan. Lưu ý rằng các trường có thể thay đổi cực kỳ khó sử dụng một cách chính xác và chỉ hiện diện để tạo điều kiện cho việc xây dựng các cấu trúc cấp cao hơn, chẳng hạn như các loại tham chiếu của Clojure, trong chính Clojure . Chúng chỉ dành cho các chuyên gia - nếu ngữ nghĩa và ngụ ý của: biến đổi dễ bay hơi hoặc: không thể đồng bộ hóa-mutable không phải là ngay lập tức rõ ràng với bạn, bạn không nên sử dụng chúng.

+2

Cảm ơn. Bạn là một goldmine của thông tin, vui mừng khi có bạn ở đây :) –

+0

Rất tốt của bạn để nói như vậy, cảm ơn. :-) –

+0

Tôi muốn nhấn mạnh ... một lần nữa ... "bạn không nên sử dụng chúng". Không sử dụng: volatile-mutable và: unynchronized-mutable. Trừ khi bạn đã biết cảnh báo này không áp dụng cho bạn và hiểu tại sao tôi lại nói lại cảnh báo ;-) – Jason

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