In primo luogo, lasciare che il codice parla:non si può prendere in prestito `self.x` come immutabile, perché` * self` è anche preso in prestito come mutabile
#[derive(Debug)]
struct Bar;
#[derive(Debug)]
struct Qux {
baz: bool
}
#[derive(Debug)]
struct Foo {
bars: Vec<Bar>,
qux: Qux,
}
impl Foo {
fn get_qux(&mut self) -> &mut Qux {
&mut self.qux
}
fn run(&mut self) {
// 1. Fails:
let mut qux = self.get_qux();
// 2. Works:
// let mut qux = &mut Qux { baz: false };
// 3. Works:
// let mut qux = &mut self.qux;
let qux_mut = &mut qux;
qux_mut.baz = true;
for bar in &self.bars {
println!("{:?}", bar);
}
}
}
fn main() {
println!("Hello, world!");
let mut foo = Foo { bars: vec!(), qux: Qux { baz: false } };
foo.run();
}
Questo errori:
error[E0502]: cannot borrow `self.bars` as immutable because `*self` is also borrowed as mutable
--> src/main.rs:33:21
|
22 | let mut qux = self.get_qux();
| ---- mutable borrow occurs here
...
33 | for bar in &self.bars {
| ^^^^^^^^^ immutable borrow occurs here
...
36 | }
| - mutable borrow ends here
Se Decommenta sia 2.
o 3.
, perché si compila bene? La funzione chiamata in 1.
non fa nulla di radicalmente diverso da 2.
o 3.
. Allora, perché è impossibile compilare 1.
?
Sebbene siano presenti many similar titled questions, non è stato possibile identificarlo chiaramente come duplicato (a parte il messaggio di errore che è lo stesso), probabilmente a causa della mia mancanza di comprensione del sistema di proprietà/prestito in Rust.
Grazie per la tua risposta completa. Mi chiedo, tuttavia, come sia possibile utilizzare 'qux' all'interno del ciclo for se necessario? –
@FelixSchlitter aggiornato. – Shepmaster
Vedo. Ma diciamo che la funzione aveva qualche logica in più, ad es. ci è voluto un id e ho recuperato 'qux' da un vec di Qux, quindi avrei dovuto aggiungere quella logica ovunque. Forse ho bisogno di ricorrere a una macro? ...So che i tipi 'HashMap' e' Vec' hanno un metodo 'get_mut', forse c'è anche qualcosa da imparare dalla loro implementazione. Dovrò fare un'altra immersione. –