结论:内部可变性(interior mutability)指在值只持有不可变引用(&T)的情况下仍能修改内部数据——通过 Cell/RefCell(单线程)或 Mutex/RwLock/原子类型(多线程),把"可变与共享互斥"的检查从编译期转移到运行时。
展开:Cell<T> 适用于 Copy 小类型,用 get/set 整体读写,无借用状态;RefCell<T> 用 borrow()/borrow_mut() 返回智能守卫,运行时维护借用计数,同一时刻出现第二个可变借用或读写混用会 panic——这正是编译期借用规则的运行时版本。所有内部可变性类型都构建在 UnsafeCell 之上,它告诉编译器禁用"不可变引用指向的数据不会变"这一优化假设。易错点:①RefCell 跨循环迭代持有 guard 极易 panic;②RefCell 不是 Sync,不能跨线程共享;③运行时检查失败是 panic 而非 UB。追问方向:内部可变性是否破坏 &T 不可变的承诺?不破坏——承诺的含义是"无同步的可变不会被观察到",编译器对含 UnsafeCell 的类型单独处理。
use std::cell::RefCell;
let cache = RefCell::new(vec![1, 2]);
let shared = &cache; // 不可变引用
shared.borrow_mut().push(3); // 运行时检查的可变
assert_eq!(&*shared.borrow(), &[1, 2, 3]);
// let a = shared.borrow_mut();
// let b = shared.borrow_mut(); // 运行时 panic: already mutably borrowed