Se si voleva serializzare cose da S-espressioni, è possibile utilizzare print-dup
:
(binding [*print-dup* true] (println [1 2 3]))
; prints [1 2 3]
(defrecord Foo [x])
; => user.Foo
(binding [*print-dup* true] (println (Foo. :foo)))
; prints #=(user.Foo/create {:x :foo})
Si noti che la stampa di una struttura che contiene, per esempio, dieci i riferimenti a un singolo vettore, seguita dalla lettura indietro ti dà una infrastruttura con dieci separati (non identical?
), sebbene equivalenti in termini di struttura (=
) vettori.
Per utilizzare questo nei casi in cui non è prevista l'implementazione predefinita, implementare il multimetodo clojure.core/print-dup
.
Inoltre, un sacco di cose in Clojure 1.2 sono java.io.Serializable
:
(every? (partial instance? java.io.Serializable)
[{1 2} #{"asdf"} :foo 'foo (fn [] :foo)])
; => true
(defrecord Foo [])
(instance? java.io.Serializable (Foo.))
; => true
noti che si dovrebbe evitare di serializzazione di runtime-creato fn
s - sono istanze di classi one-off con nomi strani e hai vinto essere in grado di deserializzarli dopo aver riavviato la JVM comunque. Con la compilazione AOT, fn
s ottengono i propri nomi di classe fissi.
Aggiornamento: Come menzionato in un commento sulla questione, Serializable
è più adatto allo stoccaggio a breve termine/trasferimento dei dati, mentre print-dup
dovrebbe essere più robusto come una soluzione di storage a lungo termine (che lavora in molte versioni di l'applicazione, Clojure ecc.). Il motivo è che print-dup
non dipende in alcun modo dalla struttura delle classi serializzate (quindi un vettore print-dup
oggi sarà ancora leggibile quando l'implementazione del vettore passa da Java a Clojure deftype
).
fonte
2010-07-21 16:57:26
Senza sapere molto su Clojure, c'è una ragione per cui questo non è realizzabile utilizzando i meccanismi di serializzazione Java standard richiamati da Clojure? – Gian
@Gian - sì è certamente possibile, ma sto cercando di imparare il "modo Clojure" di fare le cose :-) – mikera
IMO il modo Clojure è usare le strutture di Java dove forniscono buone soluzioni ai problemi che affrontano. :-) 'Serializable' può essere una buona soluzione per la memorizzazione/trasferimento a breve termine di strutture di dati. Detto questo, suppongo che per questo caso d'uso sia necessario un formato più adatto alla memorizzazione a lungo termine e questo potrebbe essere fornito da 'print-dup'. ('Serializable' potrebbe incorrere in problemi se, per esempio, la struttura delle classi implementa le modifiche delle strutture dati core Clojure:' print-dup' probabilmente no.) –