Ich schreibe ein Clojure-Programm, das XML analysiert. Als Teil davon möchte ich einen Baum der Knoten im XML-Dokument basierend auf der clojure.xml / parse-Funktion erstellen. Ich möchte jedoch, dass der Baum bidirektional ist - das heißt, jeder Knoten hat eine Liste von Kindern und einen Zeiger auf seinen Eltern. Es gibt nur ein Problem: Alle Daten sind unveränderlich und daher kann ich keinen Zeiger zum Eltern hinzufügen, ohne das Kind zu ändern, wodurch der Zeiger des Elternteils nutzlos wird.
Ich habe diese Antwort gefunden: Wie kann man zyklische (und unveränderliche) Datenstrukturen in Clojure ohne zusätzliche Indirektion erstellen?
Die vorgeschlagene Lösung scheint eine separate Indexkarte zu erstellen, die sich auf die Objekte im Inneren bezieht. Dies scheint eine riesige Menge Arbeit für eine viel schlechtere Lösung zu sein. Ich hätte kein Problem damit, dass der Baum während der Konstruktion veränderbar ist, aber ich kann nicht herausfinden, wie es gemacht werden kann. Gibt es wirklich keine Möglichkeit, einen zyklischen Zeiger in clojure zu bekommen?
Danke!
Es ist logisch unmöglich, reine unveränderliche Strukturen zyklisch zu machen, da Sie durch Hinzufügen eines Eltern- oder Kindzeigers die Struktur mutieren würden.
Es gibt einen Hack, der funktioniert, obwohl ich mir nicht sicher bin, ob ich ihn empfehlen würde: Sie können Atome in Clojure-Datenstrukturen einfügen und diese dann mutieren, um die notwendigen Links zu erstellen. z.B.
%Vor%Dies ist in vielerlei Hinsicht unangenehm:
Also, es ist möglich, wenn Sie es wirklich tun wollen ......... obwohl ich persönlich denke, dass Sie auf lange Sicht immer noch viel besser dran sind, wenn Sie Ihre Dokumentendarstellung richtig unveränderlich machen. Sie könnten vielleicht etwas mehr wie XPath Stil Orte im Dokument verwenden, wenn Sie die Struktur navigieren möchten.
Haben Sie daran gedacht, Reißverschlüsse zu verwenden?
Reißverschlüsse sind so konzipiert, dass sie das Arbeiten mit Baumstrukturen effektiv ermöglichen. Es beinhaltet grundlegende Operationen wie das Betrachten von Kindern und im übergeordnet eines Knotens, wobei auch leicht durch die Struktur iterieren .
Reißverschlüsse sind ziemlich allgemein und eingeschlossene Funktionen erlauben bereits, sie von XML zu verursachen. Ein Beispiel für die anderen Bibliotheken Seite bietet ein gutes erstes Bild davon, wie man mit ihnen arbeitet.
Für einen XML-Zipper sollten Sie
verwenden %Vor% um die Anfangsstruktur zu erstellen. Wenn Sie fertig sind, rufen Sie einfach root
auf, um die Endstruktur zu erhalten.
So etwas könnte funktionieren:
%Vor%Machen Sie das Protokoll nicht Teil der öffentlichen API und berühren Sie niemals das veränderbare Feld nach der Konstruktion und Sie haben grundsätzlich einen unveränderlichen Baum. Es wird schwierig sein, den Baum nach der Konstruktion zu modifizieren. YMMV.
Tags und Links clojure pointers data-structures immutability