序列化 – 在clojure中序列化持久数据结构

我们都知道Rich使用理想的基于哈希树的方法来实现Clojure中的持久数据结构.这种结构使我们能够操作持久数据结构而无需复制很多.

但似乎我找不到序列化这个特定结构的正确方法.例如给出:

(def foo {:a :b :c :d})
(def bar (assoc foo :e :f))
(def bunny {:foo foo :bar bar})

我的问题是:

我如何序列化兔子,使得foo的内容,即:映射到:b和:c映射到:d,在序列化内容中只出现一次?这就像倾倒结构的记忆图像.它也像序列化“内部节点”以及引用here的“叶子节点”.

附:如果这是相关的,我正在构建一个大型DAG(有向无环图),我们将这些节点与这些节点相关联,并希望序列化DAG以便以后进行反序列化.图的扩展表示(即,在repl中打印DAG时将获得的内容)是不可接受的长.

最佳答案 Davyzhu,

首先要做的事情很少:

>没有标记化策略的DAG将与DAG一样长.如果foo被引用1次或更多次,则在打印期间将依次完全实现(即显示)foo.
>对于信息的交换(序列化和反序列化),它在很大程度上取决于您的目标.例如,如果您要序列化以通过线路将其发送出去,则您将要完全执行此操作(如打印表示),或者您需要使用某些标识/标记化策略对单个数据点进行编码.当然,后者假设接收端可以通过理解标记化协议来反序列化.
>标记化策略示例可能使用Clojure meta工具,需要为每个内容块引用编码唯一键,并且DAG包含边缘由键表示的节点.

编辑::修改自原始帖子以澄清根据评论但示例
不反映DAG的层次性.

一个人为的例子:

(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取决于您.

点赞