Najpierw Speak kodu:nie może pożyczyć `self.x` jako niezmienne, ponieważ` * self` jest także zapożyczone jako zmienny
#[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();
}
This błędów:
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
Gdybym Odkomentuj albo 2.
lub 3.
, dlaczego kompilacja jest w porządku? Wywoływana funkcja w 1.
nie robi nic drastycznie innego niż 2.
lub 3.
. Dlaczego więc nie udało się skompilować 1.
?
Chociaż istnieje many similar titled questions, nie mogłem jednoznacznie zidentyfikować tego jako duplikatu (innego niż komunikat o błędzie jest taki sam), prawdopodobnie z powodu mojego niezrozumienia systemu własności/pożyczek w firmie Rust.
Dziękuję za dokładną odpowiedź. Zastanawiam się jednak, jak można wtedy użyć 'qux' wewnątrz pętli for, jeśli musiałbym? –
@FelixSchlitter zaktualizowany. – Shepmaster
Rozumiem. Ale załóżmy, że funkcja ma w sobie dodatkową logikę, np. wziął identyfikator i wydobył "qux" z vec Quxes, wtedy musiałbym dodać tę logikę wszędzie. Może muszę uciekać się do makra? ...Wiem, że typy "HashMap" i "Vec" mają metodę "get_mut", być może jest też coś do nauczenia się z ich implementacji. Będę musiał wziąć kolejne nurkowanie. –