Wenn Sie wollte die Dinge zu S-Ausdrücke serialisiert, könnten Sie print-dup
verwenden:
(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})
Beachten Sie, dass eine Struktur Druck, die, sagen wir, zehn Verweise auf einem einzigen Vektor durch das Lesen es Ihnen gefolgt zurückhält gibt eine Datenstruktur mit zehn separaten (nicht identical?
) Vektoren, die jedoch hinsichtlich der Struktur (=
) gleichwertig sind.
Um dies zu verwenden, wenn keine Standardimplementierung bereitgestellt wird, implementieren Sie die Multimethode clojure.core/print-dup
.
Auch eine Menge Dinge in Clojure 1.2 sind 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
Beachten Sie, dass Laufzeit erstellte fn
s Serialisierung vermeiden sollten - sie Instanzen von Einmal Klassen mit seltsamen Namen sind und Sie gewonnen Es ist nicht möglich, sie nach dem Neustart Ihrer JVM zu deserialisieren. Bei der AOT-Kompilierung erhalten fn
s ihre eigenen festen Klassennamen.
Update: Wie in der Frage in einem Kommentar erwähnt, ist Serializable
am besten geeignet, um die kurzfristige Lagerung/Übertragung von Daten, während print-dup
als langfristige Speicherlösung robuster sein sollte (Arbeits in vielen Versionen die Anwendung, Clojure usw.). Der Grund dafür ist, dass print-dup
in keiner Weise von der Struktur der Klassen abhängt, die serialisiert werden (so dass ein Vektor print-dup
heute noch lesbar ist, wenn die Vektorimplementierung von Java zu Clojures deftype
wechselt).
Ohne viel über Clojure zu wissen, gibt es einen Grund, warum dies nicht mit den von Clojure aufgerufenen Standard-Java-Serialisierungsmechanismen erreichbar ist? – Gian
@Gian - Ja, das ist sicherlich möglich, aber ich versuche den "Clojure-Weg" zu lernen :-) – mikera
IMO Der Clojure-Weg ist die Verwendung von Javas Einrichtungen, wo sie gute Lösungen für die Probleme bieten, die sie adressieren. :-) 'Serializable' kann eine gute Lösung für die kurzfristige Speicherung/Übertragung von Datenstrukturen sein. Ich nehme an, dass für diesen Anwendungsfall ein Format benötigt wird, das besser für die Langzeitspeicherung geeignet ist, und dies könnte von "print-dup" bereitgestellt werden. ('Serializable' könnte zu Problemen führen, wenn beispielsweise die Struktur der Klassen, die die Kern-Clojure-Datenstrukturen implementieren, sich ändert;' print-dup' wahrscheinlich nicht.) –