Ho un errore di compilazione persistente in cui Rust si lamenta del fatto che ho un prestito immutabile mentre sto cercando di mutuarlo in modo mutevole, ma il prestito immutabile proviene da un altro ambito e non sto portando nulla da esso.L'indebitamento di una HashMap dura oltre lo scopo in cui si trova?
Ho un codice che controlla un valore in una mappa e, se presente, lo restituisce, altrimenti è necessario modificare la mappa in vari modi. Il problema è che non riesco a trovare un modo per far sì che Rust mi faccia fare entrambe le cose, anche se le due operazioni sono completamente separate.
Ecco un codice privo di senso che segue la stessa struttura come il mio codice e presenta il problema:
fn do_stuff(map: &mut BTreeMap<i32, i32>, key: i32) -> Option<&i32> {
// extra scope in vain attempt to contain the borrow
{
match map.get(&key) { // borrow immutably
Some(key) => { return Some(key); },
None =>(),
}
}
// now I'm DONE with the immutable borrow, but rustc still thinks it's borrowed
map.insert(0, 0); // borrow mutably, which errors
None
}
Questo errori con:
error[E0502]: cannot borrow `*map` as mutable because it is also borrowed as immutable
--> src/main.rs:17:5
|
7 | match map.get(&key) { // borrow immutably
| --- immutable borrow occurs here
...
17 | map.insert(0, 0); // borrow mutably, which errors
| ^^^ mutable borrow occurs here
18 | None
19 | }
| - immutable borrow ends here
Questo non ha alcun senso per me. In che modo il mutuo immutabile sopravvive a tale scopo ?! Un ramo di tale match
esce dalla funzione tramite return e l'altro non fa nulla e lascia l'ambito.
Ho visto questo accadere prima dove ho erroneamente contrabbandato il prestito fuori dallo scope in qualche altra variabile, ma non è questo il caso!
È vero, il prestito sta sfuggendo allo scope tramite l'istruzione return, ma è ridicolo che blocchi i prestiti più in basso nella funzione - il programma non può eventualmente tornare AND continuare ad andare avanti! Se restituisco qualcos'altro lì, l'errore scompare, quindi penso che questo sia ciò su cui il controllore del prestito viene bloccato. Mi sembra un insetto.
Sfortunatamente, non sono stato in grado di trovare alcun modo per riscrivere questo senza colpire lo stesso errore, quindi è un bug particolarmente cattivo se questo è il caso.
Purtroppo, .entry() non è giusto per quello che questa funzione deve fare. Sono a conoscenza del problema dei bachi non lessicali, e di solito posso aggirarlo, ma in questo caso, non sono stato in grado di trovare qualcosa che non faccia un po 'di lavoro duplicato, non importa quanto brutta la soluzione è ... Inoltre di solito aggiungendo un ambito si aggira il problema, ma qui non lo fa; anche spostare un prestito in un'altra funzione non aiuta. –