Mutability
在Rust中,如果我们这样操作一个变量:
1  | let x = 5;  | 
我们就会得到一个编译错误。
如果要更改一个变量,我们需要添加mut关键字:
1  | let mut x = 5;  | 
我们也可以像下面一样更改一个变量的值:
1  | let mut x = 5;  | 
注意到y是可变变量x的可变引用,所以我们可以y来更改x的值,但是我们并不能更改y,在这里只有x是可变的。
Interior Mutability & Exterior Mutability
考虑下面一个例子:
1  | use std::sync::Arc;  | 
当clone函数被调用后,Arc<T>会增加它的引用计数,这咋一看和x是不可变的变量矛盾了不是吗?在这里,Arc<T>暴露在用户面前的是不可变的,但是其内部却是可以改变的,因为它使用了RefCell。标准库对Cell和RefCell的定义如下:
1  | Values of the Cell<T> and RefCell<T> types may be mutated through shared references (i.e. the common &T type), whereas most Rust types can only be mutated through unique (&mut T) references. We say that Cell<T> and RefCell<T> provide 'interior mutability', in contrast with typical Rust types that exhibit 'inherited mutability'.  | 
也就是说我们可以像这样操作变量:
1  | use std::cell::RefCell;  | 
borrow_mut将变量内部的可变借给了用户,这样我们就可以修改x的值了。还记得Rust的借用规则吗?我们说Rust的一个变量可以有多个不可变的借用,但是有且仅有一个可变的借用,所以如果我们这样操作:
1  | use std::cell::RefCell;  | 
那么这段代码就会在运行时崩溃(panic in runtime),这也说明了一点:RefCell在运行时执行了Rust的借用规则。
RefCell和Cell 的区别在于,Cell只能用于那么实现了CopyTrait的类型,其余的类型使用RefCell,RefCell让程序在修改变量时必须先获得一个写锁。
Cell和RefCell的运用
如果我们自定义了一个变量,变量的某些属性是可以修改的,而某些属性不能修改,那么这个时候就可以用Cell 或者RefCell了:
1  | use std::cell::Cell;  |