Eu me deparei com um erro surpreendente (para mim) ao usar RefCell e quero entender melhor por que isso está acontecendo. Eu tinha algo parecido com este código abaixo, onde eu tenho um bloco while let consumindo uma função mutável em um RefCell emprestado:
struct Foo {
val: i32,
}
impl Foo {
fn increment(&mut self) -> Option<i32> {
if self.val >= 10 {
return None;
}
self.val += 1;
Some(self.val)
}
}
fn main() {
let r = RefCell::new(Foo { val: 0 });
while let Some(v) = r.borrow_mut().increment() {
println!("iteration: {}", v);
println!("borrow: {}", r.borrow().val); // panic!: BorrowError, already mutably borrowed
}
}
Mas claramente eu não uso a referência mutável r depois que ela é criada, então por que ela ainda está viva? A maneira que eu encontrei para consertar isso é:
while let Some(v) = {
let mut borrowed = r.borrow_mut();
borrowed.increment()
} {
println!("iteration: {}", v);
println!("borrow: {}", r.borrow().val); // now this works fine
}
Mas se eu tentar remover o temporário, mesmo dentro do escopo, ele ainda quebra.
while let Some(v) = { r.borrow_mut().increment() } {
println!("iteration: {}", v);
println!("borrow: {}", r.borrow().val); // panic! BorrowError
}
Além disso, esses erros me parecem ser específicos de while let
, porque não me deparei com esse erro ao verificar alguma propriedade diretamente sem while let. Então, qual é exatamente o mecanismo/regra aqui que governa como o RefCell atualiza seu contador de empréstimo?