分配给 RefCell 中的借用对象

Dan*_*ães 0 rust borrow-checker refcell

以下代码给出了“分配借用”错误。编译器如何知道这一点?编译器是否对 RefCell 进行了特殊封装,或者语言中是否有某些内容允许它告诉编译器您有借用的值?

use std::cell::RefCell;

fn main() {
    let mut a = RefCell::new(A{a:5});
    let mut b = a.borrow_mut();
    a = RefCell::new(A{a:6});
}
Run Code Online (Sandbox Code Playgroud)

另外,为什么这段代码的工作似乎在做完全相同的事情?

use std::cell::RefCell;

fn main() {
    let mut a = Box::new(A{a:5});
    let mut b = &mut a;
    a = Box::new(A{a:6});
}
Run Code Online (Sandbox Code Playgroud)

Cha*_*man 5

编译器没有特殊的大小写RefCell。但borrow_mut()有以下签名:

pub fn borrow_mut(&self) -> RefMut<'_, T>
Run Code Online (Sandbox Code Playgroud)

因此它返回 a RefMut,在它还活着的时候保留RefCell借用的内容(因为'_,根据生命周期省略规则,它是从 借用的self)。因此,当它还活着时,您不能分配给它,RefCell因为它是借用的。

具有可变引用的第二种情况起作用的原因是,由于可变引用没有实现Drop(更准确的术语是它们没有胶水,也就是说,它们既没有实现Drop也没有任何字段(没有对于可变引用)有一个滴胶,递归地),编译器会缩短借用并尽早删除引用。但它不能用RefMutfrom做到这一点,RefCell因为它实现了Drop,因此提前删除它会改变程序行为。