面试题答案
一键面试Rust借用规则具体内容
- 同一时间,一个值要么只能有一个可变引用,要么可以有多个不可变引用:
- 可变引用允许对数据进行修改,为了避免数据竞争(多个引用同时修改数据导致未定义行为),同一时刻只能存在一个可变引用。
- 不可变引用允许多个同时存在,因为它们只读数据,不会产生数据竞争。
- 引用的生命周期必须小于或等于被借用值的生命周期:
- 引用指向的值在引用有效的期间必须一直存在,否则会出现悬垂引用(引用指向已释放的内存),导致内存安全问题。
如何保证内存安全
- 防止数据竞争:通过限制同一时间只有一个可变引用,确保不会有多个部分同时修改同一块数据,从而避免数据竞争这种未定义行为,保证内存安全。
- 防止悬垂引用:要求引用的生命周期短于或等于被借用值的生命周期,使得引用始终指向有效的内存,避免了引用到已释放内存的情况。
代码示例及违反规则的编译错误
fn main() {
let mut s = String::from("hello");
let r1 = &s; // 不可变引用r1
let r2 = &s; // 另一个不可变引用r2,符合规则
// 下面这行代码会报错,因为同一时间存在可变引用时不能有不可变引用
// let r3 = &mut s;
println!("{} and {}", r1, r2);
// 下面这行代码也会报错,因为可变引用不能与不可变引用同时存在
// let r4 = &mut s;
}
编译错误示例(针对尝试同时创建可变引用和不可变引用的情况):
error[E0502]: cannot borrow `s` as mutable because it is also borrowed as immutable
--> src/main.rs:7:13
|
5 | let r1 = &s;
| -- immutable borrow occurs here
6 | let r2 = &s;
| -- immutable borrow occurs here
7 | let r3 = &mut s;
| ^^^^^^ mutable borrow occurs here
8 |
9 | println!("{} and {}", r1, r2);
| -- immutable borrow later used here
这个错误信息表明不能对 s
进行可变借用,因为它已经被不可变借用了,违反了同一时间只能有一个可变引用或多个不可变引用的规则。