面试题答案
一键面试区别
Cell
:- 内部可变性实现方式:
Cell
通过Copy
语义来实现内部可变性。它允许在不可变引用的情况下修改其包含的数据,但是只能用于实现了Copy
trait 的类型。 - 访问方式:通过
set
方法设置值,通过get
方法获取值。
- 内部可变性实现方式:
RefCell
:- 内部可变性实现方式:
RefCell
通过运行时借用检查来实现内部可变性。它可以用于任何类型,无论该类型是否实现了Copy
trait。 - 访问方式:通过
borrow
方法获取不可变引用(Ref
),通过borrow_mut
方法获取可变引用(RefMut
)。在运行时,如果违反借用规则(如同时存在可变和不可变引用),会导致panic
。
- 内部可变性实现方式:
应用场景及选择原因
- 选择
Cell
的场景:- 当数据类型实现了
Copy
trait 且不需要担心可变和不可变引用冲突时,选择Cell
。例如,简单的数值类型。 - 示例代码:
- 当数据类型实现了
use std::cell::Cell;
fn main() {
let c = Cell::new(5);
let value = c.get();
println!("Initial value: {}", value);
c.set(10);
let new_value = c.get();
println!("New value: {}", new_value);
}
- 选择
RefCell
的场景:- 当数据类型没有实现
Copy
trait 且需要在不可变引用下进行修改时,选择RefCell
。比如,Vec
类型。 - 示例代码:
- 当数据类型没有实现
use std::cell::RefCell;
fn main() {
let rc = RefCell::new(vec![1, 2, 3]);
{
let borrow = rc.borrow();
println!("Contents: {:?}", borrow);
}
{
let mut borrow_mut = rc.borrow_mut();
borrow_mut.push(4);
}
let borrow = rc.borrow();
println!("Updated contents: {:?}", borrow);
}
在这个RefCell
的例子中,如果使用Cell
来处理Vec
,会因为Vec
没有实现Copy
trait 而导致编译错误。而RefCell
通过运行时借用检查,允许在不可变引用的情况下修改Vec
的内容。