我有一个复杂的Clojure数据结构,我想序列化 - 基本上是我正在开发的在线游戏的整个当前游戏状态,以便我可以实现保存游戏文件。
我的要求是:
有什么好建议吗?
答案 0 :(得分:11)
如果您想将事物序列化为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?
)的数据结构,尽管在结构方面是等效的({{1 }})vector。
要在没有提供默认实现的情况下使用它,请实现多方法=
。
此外,Clojure 1.2中的很多内容都是clojure.core/print-dup
:
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
- 它们是具有奇怪名称的一次性类的实例,并且无论如何重新启动JVM后都无法对它们进行反序列化。通过AOT编译,fn
可以获得自己的固定类名。
更新:正如对该问题的评论中所述,fn
最适合短期存储/传输数据,而Serializable
应该更加强大一个长期存储解决方案(适用于许多版本的应用程序,Clojure等)。原因是print-dup
在任何方面都不依赖于被序列化的类的结构(因此当向量实现从Java切换到Clojure时,今天的向量print-dup
'仍然可读。 {1}})。
答案 1 :(得分:7)
edn-format现已作为使用Clojure数据结构进行数据传输的标准发布。
它非常适合序列化Clojure数据结构/值 - 并且支持多种语言,因此也可以用作数据交换格式。
答案 2 :(得分:5)
如果一切都是Clojure数据结构,那么它已经被序列化了(b / c代码< - >数据)。只需将数据结构转储到磁盘上。要恢复,请将它们加载回来(eval)。
答案 3 :(得分:3)
对于JSON,您可以使用标准clojure-contrib.json。虽然,我记得,所有Clojure对象都应该是可序列化的......