我正在编写一个解析 XML 的 clojure 程序。作为其中的一部分,我希望基于 clojure.xml/parse 函数在 XML 文档中创建节点树。但是我希望树是双向的——也就是说,每个节点都有一个子节点列表和一个指向其父节点的指针。只有一个问题:所有数据都是不可变的,因此我无法在不更改子项的情况下“添加”指向父项的指针,从而使父项的指针无用。
我找到了这个答案:How can one create cyclic (and immutable) data structures in Clojure without extra indirection?
解决方案表明似乎正在创建一个单独的索引映射,它指的是内部的对象。对于更糟糕的解决方案来说,这似乎是一项巨大的工作。在构造过程中,树是可变的,我没有问题,但是我不知道如何做到这一点。真的没有办法在clojure中获得循环指针吗?
谢谢!
最佳答案
使纯不可变结构循环在逻辑上是不可能的,因为通过添加父或子指针,您将改变结构。
虽然我不确定我是否会推荐它,但有一个 hack 可行:您可以将原子放入 Clojure 数据结构中,然后对它们进行变异以建立必要的链接。例如
(def parent {:id 1 :children (atom nil) :parent (atom nil)})
(def child {:id 2 :children (atom nil) :parent (atom nil)})
(swap! (:children parent) conj child)
(reset! (:parent child) parent)
;; test it works
(:id @(:parent child))
=> 1
这在各方面都令人讨厌:
所以,如果你真的想这样做是有可能的......不过我个人认为,如果你让你的文档表示正确地不可变,从长远来看你仍然会好得多。如果您想导航结构,您也许可以在文档中使用更像 XPath 样式位置的内容。
关于pointers - clojure中的指针循环,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9275456/