Als Lernprojekt für Rust habe ich eine sehr einfache (funktionierende, wenn auch unvollständige) Implementierung einer einfach verknüpften Liste. Die Deklaration der structs sieht wie folgt aus:Was ist der idiomatische Weg, eine verknüpfte Liste mit einem Tail-Zeiger zu schreiben?
type NodePtr<T> = Option<Box<Node<T>>>;
struct Node<T> {
data: T,
next: NodePtr<T>,
}
pub struct LinkedList<T> {
head: NodePtr<T>,
}
Implementierung size
und push_front
beide einigermaßen geradlinig waren, obwohl tun Größe iterativ einige beinhaltete „Kampf mit dem Borge-Checker.“ Das nächste, was ich versuchen wollte, war ein tail
Zeiger auf die LinkedList
Struktur hinzufügen. um eine effiziente push_back
Operation zu ermöglichen. Hier bin ich in eine kleine Mauer gelaufen. Zuerst versuchte ich Option<&Box<Node<T>>>
und dann Option<&Node<T>>
zu verwenden. Beides führte dazu, dass man überall sträubte, aber immer noch nicht in der Lage war, dem Lebensdauertest zuzustimmen, dass tail
gültig wäre.
Ich habe zu dem vorläufigen Schluss, da gekommen, dass es mit diesen Definitionen nicht möglich ist: dass es keine Möglichkeit gibt zu Garantie an den Compiler, die tail
in den Orten gültig wäre, dass ich denke, dass es gültig ist. Die einzige Möglichkeit, dies zu erreichen, ist, alle meine Zeiger Rc<_>
oder Rc<RefCell<_>>
zu haben, denn das sind die einzigen sicheren Möglichkeiten, zwei Dinge auf dasselbe Objekt (den letzten Knoten) zu richten.
Meine Frage: Ist das die richtige Schlussfolgerung? Allgemeiner ausgedrückt: Was ist die idiomatische Rust-Lösung für nicht-pointierte Zeiger in Datenstrukturen? In meinen Augen scheint Referenzzählen für so etwas so schwer zu sein, dass ich etwas verpassen muss. (Oder vielleicht habe ich meine Meinung in die richtige Einstellung nur noch nicht für die Speichersicherheit bekommen.)
Sie haben Recht; es ist nicht möglich, Zyklen im sicheren Rust ohne geteilten Besitz auszudrücken, wie es durch Dinge wie 'Rc' bereitgestellt wird. –
Das sieht nach der richtigen Antwort auf meine Frage aus, aber ich möchte auch keine gemeinsame Eigentümerschaft haben. Ich nehme an, dass ich mit 'std :: rc :: Weak 'zusätzlich zu' Rc' herumspielen werde, da ich gerade bemerkt habe, dass die erste existiert. Danke für die schnelle Antwort! – GrandOpener
* Meiner Meinung nach scheint die Referenzzählung für etwas so Einfaches schwer zu sein * => Wenn Sie anfangen, Ihre Augen für Eigentumsfragen zu öffnen (wer besitzt jedes Stück Daten), werden Sie feststellen, dass Ihr Eindruck von Einfachheit falsch ist:) –