java - Serialización de la estructura de datos de clojure
serialization (4)
Si quisiera serializar cosas a expresiones S, podría usar 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})
Tenga en cuenta que la impresión de una estructura que contiene, por ejemplo, diez referencias a un solo vector seguido de su lectura le da una estructura de datos con diez separados (¿no son identical?
), Aunque equivalentes en términos de estructura ( =
) vectores.
Para usar esto en los casos en que no se proporciona una implementación predeterminada, implemente el clojure.core/print-dup
.
Además, muchas cosas en Clojure 1.2 son 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
Tenga en cuenta que debe evitar la serialización de fn
s creados por el tiempo de ejecución: son instancias de clases únicas con nombres extraños y no podrá deserializarlas después de reiniciar su JVM de todos modos. Con la compilación AOT, los fn
obtienen sus propios nombres de clase fijos.
Actualización: Como se mencionó en un comentario sobre la pregunta, Serializable
es más adecuado para el almacenamiento / transferencia de datos a corto plazo, mientras que el servicio de print-dup
debe ser más sólido como solución de almacenamiento a largo plazo (funciona en muchas versiones de la aplicación, Clojure etc.). La razón es que print-dup
no depende de ninguna manera de la estructura de las clases que se están serializando (por lo tanto, una print-dup
vector print-dup
''d todavía se podrá leer cuando la implementación vectorial cambie de Java a deftype
de Clojure).
Tengo una compleja estructura de datos de Clojure que me gustaría serializar, básicamente todo el estado actual del juego para un juego en línea que estoy desarrollando para que pueda implementar guardar archivos de juegos.
Mis requerimientos son:
- Alguna forma de formato de texto legible para el ser humano (probablemente preferiría las expresiones s, JSON y XML en ese orden, pero abierto a otros)
- Admite todas las estructuras de datos, palabras clave y primitivas de Clojure habituales
- Capacidad para proporcionar funciones personalizadas de serialización / deserialización para clases Java personalizadas, registros de fallos, etc. (esto es importante porque necesito hacer algo como readResolve de Java en varios casos)
- El buen rendimiento es bueno tenerlo
¿Alguna buena recomendación?
Si todo es una estructura de datos de Clojure, entonces ya está serializado (b / c de código <-> datos). Simplemente volcar las estructuras de datos en el disco. Para restaurar, vuelva a cargarlos y (eval).
para JSON puede usar clojure-contrib.json estándar. Aunque, como recuerdo, todos los objetos de Clojure deberían ser serializables ...
edn-format ahora se ha lanzado como un estándar para la transferencia de datos utilizando las estructuras de datos de Clojure.
Es una buena opción para serializar estructuras / valores de datos de Clojure, y es compatible con múltiples idiomas, por lo que también se puede utilizar como un formato de intercambio de datos.