Ich versuche, eine rekursive Datenstruktur iterativ zu navigieren, um Elemente an einer bestimmten Position einzufügen. Um mein begrenztes Verständnis bedeutet dies eine veränderbare Bezugnahme auf die Wurzel der Struktur zu nehmen und sie nacheinander durch einen Verweis auf seine Folger ersetzt:Erhalten einer veränderbaren Referenz durch Iterieren einer rekursiven Struktur
type Link = Option<Box<Node>>;
struct Node {
next: Link
}
struct Recursive {
root: Link
}
impl Recursive {
fn back(&mut self) -> &mut Link {
let mut anchor = &mut self.root;
while let Some(ref mut node) = *anchor {
anchor = &mut node.next;
}
anchor
}
}
jedoch dies nicht gelingt:
error[E0499]: cannot borrow `anchor.0` as mutable more than once at a time
--> src/main.rs:14:24
|
14 | while let Some(ref mut node) = *anchor {
| ^^^^^^^^^^^^
| |
| second mutable borrow occurs here
| first mutable borrow occurs here
...
18 | }
| - first borrow ends here
error[E0506]: cannot assign to `anchor` because it is borrowed
--> src/main.rs:15:13
|
14 | while let Some(ref mut node) = *anchor {
| ------------ borrow of `anchor` occurs here
15 | anchor = &mut node.next;
| ^^^^^^^^^^^^^^^^^^^^^^^ assignment to borrowed `anchor` occurs here
error[E0499]: cannot borrow `*anchor` as mutable more than once at a time
--> src/main.rs:17:9
|
14 | while let Some(ref mut node) = *anchor {
| ------------ first mutable borrow occurs here
...
17 | anchor
| ^^^^^^ second mutable borrow occurs here
18 | }
| - first borrow ends here
Dies macht Sinn, da sich sowohl anchor
als auch node
auf die gleiche Struktur beziehen, aber nach der Destrukturierung kümmert es mich eigentlich nicht mehr um anchor
. Wie kann back()
mit Safe Rust korrekt implementiert werden?
Awesome! Nur damit ich verstehe, was hier passiert: 1) "Anker" hat die Anfangsreferenz 2) "tmp" wird von "Anker" bewegt, was bedeutet, dass "Anker" keine Referenz mehr ist 3) 'tmp' kann sicher sein geliehen von, wie es fallen gelassen wird, sobald die Schleifeniteration endet –
Das großartigste hier ist, dass ich anfänglich den 'anchor = tmp; 'im' else'-Zweig vergaß und rustc einen Fehler dafür erzeugte ...Wie auch immer, ja, die Idee ist, dass man Anker nicht zuordnen kann, solange es ausgeliehen ist, also übertragen wir den Verweis auf "tmp" und leihen dann "tmp" aus, um "anchor" zuzuweisen. –
Dies kann eigentlich ziemlich knapp geschrieben werden, weil wir 'is_some()' auf 'anchor' vor dem Verschieben aufrufen können. Ich habe deinen Beitrag bearbeitet. –