RefCell 内部可变性
RefCell<T> 运行时借用检查、borrow/borrow_mut、Rc<RefCell<T>> 模式
RefCell 内部可变性
RefCell<T> 把借用检查推迟到运行时——即使外部是不可变引用,内部也可以修改。经典组合:Rc<RefCell<T>>。
学完本章你将: 掌握 RefCell borrow/borrow_mut、运行时检查、Rc<RefCell
RefCell 基础
rust
use std::cell::RefCell;
fn main() {
let data = RefCell::new(42);
// 不可变借用(运行时检查)
{
let borrowed = data.borrow();
println!("{}", *borrowed); // 42
} // borrow 离开作用域——归还
// 可变借用
{
let mut borrowed = data.borrow_mut();
*borrowed = 100;
}
println!("{}", data.borrow()); // 100
}
Rc> —— 共享可变数据
rust
use std::rc::Rc;
use std::cell::RefCell;
#[derive(Debug)]
struct Node {
value: i32,
children: RefCell<Vec<Rc<Node>>>,
}
fn main() {
let leaf = Rc::new(Node {
value: 3,
children: RefCell::new(vec![]),
});
let branch = Rc::new(Node {
value: 5,
children: RefCell::new(vec![Rc::clone(&leaf)]),
});
// 即使 branch 是 Rc(不可变引用),也能修改 children
branch.children.borrow_mut().push(Rc::new(Node {
value: 7,
children: RefCell::new(vec![]),
}));
}
运行时借用规则
rust
let data = RefCell::new(42);
let r1 = data.borrow();
// let r2 = data.borrow_mut(); // ❌ panic——已有不可变借用
drop(r1);
let mut r2 = data.borrow_mut();
// let r3 = data.borrow(); // ❌ panic——已有可变借用
⚠️ RefCell 在运行时检查规则——违反会 panic。编译器不会阻止你写出有问题的代码。