我在使用 RefCell 时遇到了一个令我惊讶的错误,我想更好地了解为什么会发生这种情况。我有类似下面的代码,其中我有一个 while let 块使用借用的 RefCell 上的可变函数:
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
}
}
但显然我在创建 r 可变引用后没有使用它,那么为什么它还活着? 我发现解决这个问题的方法是:
while let Some(v) = {
let mut borrowed = r.borrow_mut();
borrowed.increment()
} {
println!("iteration: {}", v);
println!("borrow: {}", r.borrow().val); // now this works fine
}
但是如果我尝试删除临时的,即使在范围内,它仍然会中断。
while let Some(v) = { r.borrow_mut().increment() } {
println!("iteration: {}", v);
println!("borrow: {}", r.borrow().val); // panic! BorrowError
}
此外,我认为这些错误是 所特有的while let
,因为当我直接检查某些属性而不使用 while let 时,我没有遇到此错误。那么这里究竟是什么机制/规则控制着 RefCell 如何更新其借用计数器?