Serialization 在clojure中序列化持久数据结构
我们都知道,Rich使用了一种理想的基于哈希树的方法来实现Clojure中的持久数据结构。这种结构使我们能够在不进行大量复制的情况下操作持久数据结构 但我似乎找不到序列化这个特定结构的正确方法。例如:Serialization 在clojure中序列化持久数据结构,serialization,clojure,Serialization,Clojure,我们都知道,Rich使用了一种理想的基于哈希树的方法来实现Clojure中的持久数据结构。这种结构使我们能够在不进行大量复制的情况下操作持久数据结构 但我似乎找不到序列化这个特定结构的正确方法。例如: (def foo {:a :b :c :d}) (def bar (assoc foo :e :f)) (def bunny {:foo foo :bar bar}) 我的问题是: 我如何序列化小兔子,使foo的内容,即:a映射到:b和:c映射到:d的内容在序列化内容中只出现一次?这就像是在倾倒
(def foo {:a :b :c :d})
(def bar (assoc foo :e :f))
(def bunny {:foo foo :bar bar})
我的问题是:
我如何序列化小兔子
,使foo
的内容,即:a
映射到:b
和:c
映射到:d
的内容在序列化内容中只出现一次?这就像是在倾倒建筑物的记忆图像。这也类似于序列化引用的“内部节点”和“叶节点”
p.S.如果这是相关的,我正在构建一个大的DAG(有向无环图),在这里我们assoc
相当多地将这些节点链接到这些节点,并希望序列化DAG以便以后反序列化。图形的扩展表示(即在repl中打印DAG时将获得的内容)太长,令人无法接受。Davyzhu
首先是几件事:
foo
被引用1次或多次,则在打印过程中,每一次都将被完全实现(即显示)(def node1 {:a :b :c :d})
(def node2 {:e :f})
(def dictionary {:foo node1 :bar node2})
(def DAG [:bunny [:foo :bar]])
(println DAG) ; => [:bunny [:foo :bar]]
(defn expand-dag1
[x]
(if (keyword? x)
(get dictionary x x)
x))
(println (w/postwalk expand-dag1 DAG)) ; => [:bunny [{:a :b, :c :d} {:e :f}]]
注意:使用向量、地图、列表等来表达您的DAG取决于您。这是一个选项(在Clojurescript中不起作用,以防出现问题),通常可能会被视为一个坏主意,但无论如何都值得一提
如果我理解您的问题,您希望(def bunny{:foo foo:bar bar})中的foo
不被“粘贴”为完整副本,而是保留对(def foo..)
的“引用”,以便原始foo
映射只序列化一次
<> LI> 一种技术,我认为虽然不一定会鼓励(并且在耗尽了其他选项,比如Frank C.的数据结构的重新组织化)之后,将序列化代码<代码> Bunn,而不是结构本身。然后将代码字符串读回并
eval
it。只有在bunny的结构没有改变的情况下,或者如果它改变了,您可以轻松地构建一个包含相关符号(而不是这些符号的内容)的bunny地图字符串,这才有效
但更好的方法是只序列化“原始”数据结构,如映射foo
和bar
,然后在读回这些数据结构后构建bunny
——也序列化结构,但不序列化bunny的内容。我相信这就是弗兰克的答案
值得注意的是,如果bunny的结构确实是动态变化的,那么您可以按照1中的建议创建一组符号。在上面,这意味着您还可以使用工具来构建bunny的表示,如图2所示。以上,这将是更好的
因为代码是数据,所以选择1。作为lisp程序员,我们可以使用这种灵活性的一个例子,但这并不意味着没有更好的选项。您是指键:a
和:c
及其相应的值?还是仅仅是:a
和:b
的元素?@cfrick感谢您的编辑。foo
的全部内容应该在构建bar
时重用,我希望序列化只包含一次foo
的内容。我将再次编辑这个问题以澄清问题。如果您还可以指定您的期望值-bunny的序列化结果应该是什么样的,那就太好了。对我来说(strbunny)的结果是{:foo{:c:d,:a:b},:bar{:e:f,:c:d,:a:b},这似乎是正确的。但我不明白你说的是什么意思“只包含一次foo的内容。@ViktorK。我不特定于任何实现,只要我不必完全实现DAG。正如@Frank在下面的回答中所说的,我希望能够实现自动标记化,就像用于实现PersistentMap
或PersistentVector
的标记化一样。您能再次检查您设计的示例吗?我觉得有点难以理解。为什么[:node foo]
会在其中出现两次?我们使用源节点表示DAG,其余节点间接引用。此外,你是说我必须自己实现标记化协议,即使这已经在幕后完成了吗?Davyzhu:希望编辑有帮助,我将更多的内容映射到你的示例中,以反映DAG的一些结构。我使用向量是基于我对本体的经验。我明白了。您将展示如何标记图形并区分标记和内容。我将尝试遍历图形,并执行此操作。谢谢hellofunk:我也在想类似的事情。在最近的编辑中,我添加了一个“字典”,在现实世界中,它将由一个atom来管理,这是最有效的。这很有趣!但是