deftype
L'impostazione predefinita è che i campi siano immutabili; per sovrascriverlo, è necessario annotare i nomi dei campi che devono essere sostituiti con i metadati appropriati. Inoltre, la sintassi per set!
dei campi di istanza è diversa. Un esempio di implementazione per rendere il lavoro di cui sopra:
(deftype Point [^{:volatile-mutable true} x]
IPoint
(getX [_] x)
(setX [this v] (set! x v)))
C'è anche :unsynchronized-mutable
. La differenza è che i nomi suggerirebbero a uno sviluppatore Java esperto. ;-) Si noti che la fornitura sia di annotazione ha l'ulteriore effetto di rendere il campo privato, in modo che l'accesso campo diretto non è più possibile:
(.getX (Point. 10)) ; still works
(.x (Point. 10)) ; with annotations -- IllegalArgumentException, works without
Inoltre, 1.2 sarà probabilmente sostenere la sintassi ^:volatile-mutable x
come abbreviazione di ^{:volatile-mutable true} x
(questo è già disponibile su alcuni dei nuovi rami numerici).
Entrambe le opzioni sono menzionate in (doc deftype)
; Segue la parte rilevante: attenzione all'ammonizione!
campi può essere qualificato con i metadati: volatili mutevole vero o: unsynchronized-mutabile vero, a questo punto (set lontano Aval!) Sarà sostenuta nel metodo corpi. Si noti bene che i campi mutabili sono estremamente difficili da usare correttamente e sono presenti solo per facilitare la creazione di più elevati costrutti di livello , come i tipi di riferimento di Clojure, in Clojure stesso. Sono solo per esperti - se la semantica e le implicazioni di: volatile-mutable o: unsynchronized-mutable non sono immediatamente apparenti, non dovresti usarli.
fonte
2010-06-28 15:16:51
Grazie. Sei una miniera d'oro di informazioni, felice di averti qui :) –
Piacere a dirlo, grazie. :-) –
Voglio sottolineare ... di nuovo ... "non dovresti usarli". Non utilizzare: volatile-mutable e: non sincronizzato-mutabile. A meno che tu non sappia già che questo avviso non si applica a te e capisci perché sto affermando di nuovo l'avviso ;-) – Jason