两个概念:
- Alias的意思是“别名”。如果一个变量可以通过多种Path来访问,那它们就可以互相看作alias。Alias意味着“共享”,我们可以通过多个入口访问同一块内存。
- Mutation的意思是“改变”。如果我们通过某个变量修改了一块内存,就是发生了mutation。Mutation意味着拥有“修改”权限,我们可以写入数据。
共享不可变,可变不共享
编译错误示例
通过不同的Path访问同一块内存p, *p1, * p2,所以它们存在“共享”。而且它们都只有只读的权限,所以它们存在“共享”,不存在“可变”。因此它一定是安全的。
fn main() {//正常
let i = 0;
let p1 = & i;
let p2 = & i;
println! ("{} {} {}", i, p1, p2);
}
在存在只读借用的情况下,变量绑定i和p1已经互为alias,它们之间存在“共享”,因此必须避免“可变”。这段代码违反了“共享不可变”的原则。
fn main() {//报错
let mut i = 0;
let p1 = & i;
i = 1;
}
因为这段代码中不存在“共享”。在可变借用存在的时候,编译器认为原来的变量绑定i已经被冻结(frozen),不可通过i读写变量。此时有且仅有p1这一个入口可以读写变量。
fn main() {//正常
let mut i = 0;
let p1 = &mut i;
*p1 = 1;
}
因为p1、p2都是可变借用,它们都指向了同一个变量,而且都有修改权限,这是Rust不允许的情况,因此这段代码无法编译通过。
fn main() {//报错
let mut i = 0;
let p1 = &mut i;
let p2 = &mut i;
}
&mut型借用也经常被称为“独占指针”, &型借用也经常被称为“共享指针”。