面试题答案
一键面试常见规避方案:使用 Rc<T>
和 RefCell<T>
实现步骤
- 引入必要的模块:
use std::cell::RefCell; use std::rc::Rc;
- 创建
Rc<RefCell<T>>
类型的数据:let shared_data = Rc::new(RefCell::new(vec![1, 2, 3]));
- 创建多个引用:
let data1 = Rc::clone(&shared_data); let data2 = Rc::clone(&shared_data);
- 通过
RefCell
进行可变借用:{ let mut inner1 = data1.borrow_mut(); inner1.push(4); } { let inner2 = data2.borrow(); println!("{:?}", inner2); }
可能存在的问题
- 运行时借用检查:与编译时的借用检查不同,
RefCell
在运行时进行借用检查。如果违反借用规则,会导致panic!
,例如同时进行多个可变借用。let shared = Rc::new(RefCell::new(0)); let a = Rc::clone(&shared); let b = Rc::clone(&shared); let mut inner_a = a.borrow_mut(); let inner_b = b.borrow(); // 这里会 panic,因为同时存在可变借用和不可变借用
- 性能开销:
RefCell
内部使用Cell
来跟踪借用状态,这会带来一些性能开销,相比编译时借用检查,运行时检查会增加时间和空间复杂度。 - 线程安全性:
Rc
和RefCell
都不是线程安全的。如果需要在多线程环境下共享数据,应该使用Arc
和Mutex
或RwLock
等线程安全的替代品。