2010-06-28 9 views
19

Ich versuche Clojure 1.2, speziell veränderbare Felder, die in deftype nach der clojure.org documentation unterstützt werden.Veränderbare Felder in Clojure deftype?

Aber ich kann das Set nicht funktionieren. Wie lautet die Syntax zum Aktualisieren eines Felds? Oder ist Mutabilität noch nicht implementiert?

(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 

Verwenden eines 1.2 Schnappschusses von vor ein paar Tagen.

Antwort

40

deftype Standard ist immer noch die Felder unveränderlich zu haben; Um dies zu überschreiben, müssen Sie die Namen der Felder kommentieren, die mit geeigneten Metadaten veränderbar sein sollen. Außerdem ist die Syntax für Instanzfelder set! unterschiedlich. Eine beispielhafte Implementierung der obigen Arbeit zu machen:

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

gibt es auch :unsynchronized-mutable. Der Unterschied ist, wie die Namen einem erfahrenen Java-Entwickler nahelegen würden. ;-) Beachten Sie, dass das Feld privat machen entweder Annotation hat den zusätzlichen Effekt bereitstellt, so dass ein direkter Zugang Feld nicht mehr möglich ist:

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

Auch wird, 1.2 unterstützen wahrscheinlich die Syntax ^:volatile-mutable x als Abkürzung für ^{:volatile-mutable true} x (dies ist bereits für einige der neuen Numerikzweige verfügbar).

Beide Optionen sind in (doc deftype) erwähnt; der relevante Teil folgt - beachten Sie die Ermahnung!

Felder können mit den Metadaten zu qualifizieren: volatile-wandelbar wahr oder: unsynchronisierte-wandelbar wahr, an welcher Stelle (Set afield Aval!) Wird in Verfahren Gremien unterstützt. Beachten Sie, dass veränderbare Felder extrem schwierig zu verwenden richtig sind, und nur vorhanden sind, um das Erstellen von höheren Level-Konstrukte, wie Clojure-Referenztypen, in Clojure selbst zu erleichtern. Sie sind nur für Experten - wenn die Semantik und Implikationen von: volatile-mutable oder: unsynchronized-mutable nicht sofort ersichtlich sind, sollten Sie sie nicht verwenden.

+2

Danke. Sie sind eine Goldgrube von Informationen, froh, Sie hier zu haben :) –

+0

Schön von Ihnen zu sagen, danke. :-) –

+0

Ich möchte betonen ... wieder ... "du solltest sie nicht benutzen". Verwenden Sie nicht: volatile-mutable und: unsynchronized-mutable. Sofern Sie nicht bereits wissen, dass diese Warnung nicht auf Sie zutrifft und Sie verstehen, warum ich die Warnung nochmals sage ;-) – Jason

Verwandte Themen