sto cercando di navigare una struttura dati ricorsiva iterativamente per inserire elementi in una certa posizione. La mia comprensione limitata, ciò significa assumere un riferimento mutevole alla radice della struttura e successivamente sostituzione con un riferimento alla sua follower:Ottenere un riferimento mutevole iterando una struttura ricorsiva
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
}
}
Tuttavia, questo fallisce:
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
Questo ha senso in quanto sia anchor
che node
si riferiscono alla stessa struttura, ma in realtà non mi interessa più di anchor
dopo averlo distrutto.
Come potrebbe back()
essere implementato correttamente utilizzando Rust sicuro?
Impressionante! Solo per capire cosa sta succedendo qui: 1) 'anchor' ha il riferimento iniziale 2)' tmp' viene spostato da 'anchor', il che significa che' anchor'ist non è più un riferimento 3) 'tmp' può essere sicuro preso in prestito dal momento in cui viene eliminato non appena termina l'iterazione del loop –
Il più fantastico, qui, è che inizialmente ho dimenticato il 'anchor = tmp;' nel ramo 'else' e rugc ha generato un errore per esso ...comunque, sì, l'idea è che non è possibile riassegnare 'anchor' mentre è in prestito, quindi trasferiamo il riferimento a' tmp' e poi prendiamo in prestito 'tmp' per assegnare' anchor'. –
Questo può essere scritto in modo abbastanza conciso perché possiamo chiamare 'is_some()' su 'anchor' prima di spostarlo. Ho modificato il tuo post. –