Serialization 序列化拉链?

Serialization 序列化拉链?,serialization,clojure,zipper,Serialization,Clojure,Zipper,我在repl上打印拉链时看到了这些数据。我在想,这可能是我序列化拉链所需的所有数据?是否可以从提供的数据中反序列化拉链 我正在寻找类似下面想象的zip/serialize和zip/deserialize函数 repl> (-> root zip/down zip/right) [{:answer-keys [5 6], :id 3} {:l [{:id 2, :answer-keys []}], :pnodes [{:answer-keys [2 3 4], :id 1}], :pp

我在repl上打印拉链时看到了这些数据。我在想,这可能是我序列化拉链所需的所有数据?是否可以从提供的数据中反序列化拉链

我正在寻找类似下面想象的zip/serialize和zip/deserialize函数

repl> (-> root zip/down zip/right)
[{:answer-keys [5 6], :id 3} {:l [{:id 2, :answer-keys []}], :pnodes [{:answer-keys [2 3 4], :id 1}], :ppath nil, :r ({:answer-keys [7], :id 4})}]

有人知道怎么做吗?

拉链的神奇之处在于,它是一种数据结构,表示生成任意修改版本的树结构所需的一切。拉链打印和阅读都很好,因为它们是正确的值,不需要任何状态

您可以使用
pr str对其进行“序列化”,并使用
read对其进行“反序列化”

制作拉链:

(def s (zip/serialize (-> root zip/down zip/right))) ;; s is a string
(def d (zip/deserialize s)) ;; d is a zipper location
;;And I can go on using the deserialized zipper d without any difficulty.
将其序列化为字符串:

user> (zip/vector-zip [[1 [2]][3][4]])
[[[1 [2]] [3] [4]] nil]
user> (def s (zip/vector-zip [[1 [2]][3][4]]))
#'user/s
user> s
[[[1 [2]] [3] [4]] nil]
重读一遍:

user> (def serialized-s (pr-str (zip/next s)))
#'user/serialized-s
user> serialized-s
"[[1 [2]] {:l [], :pnodes [[[1 [2]] [3] [4]]], :ppath nil, :r ([3] [4])}]"
对结果做点什么:

user> (def deserialized-s (read-string "[[1 [2]] {:l [], :pnodes [[[1 [2]] [3] [4]]], :ppath nil, :r ([3] [4])}]"))
#'user/deserialized-s

要扩展亚瑟的答案:

您可能还需要序列化clojure.zip放在其拉链上的元数据,因为它似乎在那里跟踪
分支?
/
子节点
/
生成节点
函数。大概是

user> (zip/root deserialized-s)
[[1 [2]] [3] [4]]

哇,太酷了。我在想,这是在一路上创造一个封闭。哈哈。我唯一剩下的问题是为什么print str序列化表达式,而read string只反序列化字符串中的第一项?它们并不完全“匹配”,这似乎有点奇怪。
print
函数系列是供人使用的,而不是用于序列化。例如,字符串和符号打印相同,因此信息丢失。相反,请使用
pr str
,它以计算机友好的格式打印(或多或少与
read string
相反)。@StephenCagle如果您有另一个与此基本无关的问题,我建议您将其作为一个问题来问,而不是作为对此处某个答案的评论。但简而言之,没有不一致:
print string
将一个值打印到一个字符串,而
read string
从字符串中读取一个值。@amalloy,修复:)幸运的是,在这种情况下,输出结果是相同的:正如我所理解的,zippers,它们实际上表示子项的状态以及正确类型的导航操作。这并不特别有用,因为所有元数据值都是函数,通常无法读取。
(defn serialize [zipper]
  (binding [*print-meta* true]
    (pr-str zipper)))

(def deserialize read-string)