Ответ 1
Если вы хотите сериализовать вещи в S-выражениях, вы можете использовать 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})
Обратите внимание, что печать структуры, которая содержит, скажем, десять ссылок на один вектор, а затем их чтение, дает вам структуру данных с десятью отдельными (не identical?
), хотя и эквивалентными по векторам структуры (=
).
Чтобы использовать это в случаях, когда нет реализации по умолчанию, реализуйте мультимед clojure.core/print-dup
.
Кроме того, много вещей в Clojure 1.2: 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
Обратите внимание, что вам следует избегать сериализации созданного во время выполнения fn
- это экземпляры одноразовых классов со странными именами, и вы не сможете их десериализовать после перезапуска вашей JVM. С помощью компиляции AOT fn
получают собственные фиксированные имена классов.
Обновление. Как упоминалось в комментарии к вопросу, Serializable
лучше всего подходит для кратковременного хранения/передачи данных, тогда как print-dup
должен быть более надежным как долгосрочное решение для хранения (работающее во многих версиях приложения, Clojure и т.д.). Причина в том, что print-dup
никоим образом не зависит от структуры сериализуемых классов (поэтому вектор print-dup
'd сегодня будет доступен для чтения, когда векторная реализация переключается с Java на Clojure deftype
).