Ich versuche, eine generische Liste als Übung zu programmieren - ich weiß, dass es bereits von der Syntax unterstützt wird, ich versuche nur zu sehen, ob ich eine rekursive Datenstruktur codieren kann. Wie sich herausstellt, kann ich nicht. Ich stoße auf eine Wand, wenn ich auf mehr als ein Feld eines eigenen Strukturwerts zugreifen möchte.Wie mehrere Strukturfelder zu binden, ohne Fehler "Use verschobenen Wert" zu erhalten?
Was ich tue, ist im Grunde diese - ich definieren eine Struktur, die eine Liste halten wird: gerade dargestellt wird
struct ListNode<T> {
val: T,
tail: List<T>
}
struct List<T>(Option<Box<ListNode<T>>>);
Leere Liste von List(None)
.
Nun möchte ich auf eine Liste anhängen können:
impl<T> List<T> {
fn append(self, val: T) -> List<T> {
match self {
List(None) => List(Some(Box::new(ListNode { val: val, tail: List(None) }))),
List(Some(node)) => List(Some(Box::new(ListNode { val: node.val, tail: node.tail.append(val) })))
}
}
}
Ok, so dass mit einem Fehler fehlschlägt „bewegter Wert verwendet: Knoten“ bei node.tail mit einer Erklärung, dass es bei "node.val" verschoben. Das ist verständlich.
Also suche ich nach Möglichkeiten, mehr als ein Feld einer Struktur zu verwenden, und ich finde dies: Avoiding partially moved values error when consuming a struct with multiple fields
Großen, also werde ich das tun:
List(Some(node)) => {
let ListNode { val: nval, tail: ntail } = *node;
List(Some(Box::new(ListNode { val: nval, tail: ntail.append(val) })))
}
Nun, nein, Still-Node wird bei der Zuweisung verschoben ("Fehler: Verwendung des verschobenen Wertes 'node'" at "tail: ntail"). Scheinbar funktioniert das nicht mehr wie im Link.
ich auch Refs habe versucht, mit:
List(Some(node)) => {
let ListNode { val: ref nval, tail: ref ntail } = *node;
List(Some(Box::new(ListNode { val: *nval, tail: (*ntail).append(val) })))
}
Dieses Mal ist die Dekonstruktion geht, sondern die Schaffung des neuen Knotens nicht mit „Fehler: kann nicht aus geliehenen Inhalte bewegen“.
Fehle ich etwas offensichtlich hier? Wenn nicht, was ist der richtige Weg, um auf mehrere Felder einer Struktur zuzugreifen, die nicht als Referenz übergeben werden?
Vielen Dank im Voraus für jede Hilfe!
EDIT: Oh, ich sollte wahrscheinlich hinzufügen, dass ich Rust 1.1 stabil verwende.
Vielen Dank! Das funktioniert in der Tat :) Warum würde Box so funktionieren? Gibt es eine vernünftige Erklärung? – ebvalaim
Ich bin mir ziemlich sicher, dass es mit der Tatsache zu tun hat, dass der Unboxing-Deref eine Compiler-Magie ist. –
Hier ist der entsprechende Fehler: https://github.com/rust-lang/rust/issues/16223 –