Nel codice seguente (playground):non possono prendere in prestito `x` come mutabile più di una volta in un momento
struct Node {
datum: &'static str,
edges: Vec<Node>,
}
fn add<'a>(node: &'a mut Node, data: &'static str) -> &'a Node {
node.edges
.push(Node {
datum: data,
edges: Vec::new(),
});
&node.edges[node.edges.len() - 1] // return just added one
}
fn traverse<F>(root: &Node, callback: &F)
where F: Fn(&'static str)
{
callback(root.datum);
for node in &root.edges {
traverse(node, callback);
}
}
fn main() {
let mut tree = Node {
datum: "start",
edges: Vec::new(),
};
let lvl1 = add(&mut tree, "level1");
traverse(&mut tree, &|x| println!("{:}", x)); //I actually don't need mutability here
}
ho questo tipo di errore:
error[E0499]: cannot borrow `tree` as mutable more than once at a time
--> src/main.rs:32:19
|
30 | let lvl1 = add(&mut tree, "level1");
| ---- first mutable borrow occurs here
31 |
32 | traverse(&mut tree, &|x| println!("{:}", x)); //I actually don't need mutability here
| ^^^^ second mutable borrow occurs here
33 | }
| - first borrow ends here
La mia domanda sembra essere molto simile a Why does Rust want to borrow a variable as mutable more than once at a time?, ma non ne sono sicuro. Se è così, c'è una soluzione alternativa per questo caso?
L'inferno è che se il compilatore non può elaborare il corpo della funzione per determinare le parti interessate delle strutture, e non c'è modo di dare un indizio su questo ... Quindi a) Perché hanno fatto questo? (nel nome delle gare di dati?); b) Come suggeriscono di codificare in tali situazioni? – tower120
Il compilatore può elaborare i corpi delle funzioni quando sono nella tua cassa, ma come suggerisci di gestire le dipendenze esterne * binary *? Non contengono informazioni sufficienti per il compilatore. Pertanto, questo è l'unico modo in cui il modello di proprietà e il prestito possono essere resi sani, quindi sì, "hanno fatto questo" per un sacco di cose, compresa la lotta alle corse di dati. Per quanto riguarda il codice in tali situazioni, beh, non c'è modo di ristrutturare il codice, ad esempio, nel tuo caso specifico puoi dividere l'inserimento e la ricerca in due metodi, dove insert non restituirà nulla, evitando così il prestito . –
"Il compilatore può elaborare i corpi delle funzioni quando sono nella tua cassa, ma come suggerisci di gestire le dipendenze binarie esterne?" - Segna come non sicuro, non gestirlo (sono esterni, dopotutto). "Per quanto riguarda come codificare in tali situazioni, beh, non c'è modo di ristrutturare il tuo codice" - Non mi piace. Ristruttura codice solo per avere un senso per il compilatore? Non suona affatto ... – tower120