面试题答案
一键面试Rust借用机制防止数据竞争原理
在Rust中,借用规则规定:
- 同一时间内,一个数据结构要么只能有一个可变引用(可变借用),要么可以有多个不可变引用(不可变借用),但不能同时存在可变引用和不可变引用。
- 引用的作用域必须在其所借用的数据结构的作用域之内。
这样的规则确保了在任何时刻,对数据结构的写操作(通过可变引用)是独占的,读操作(通过不可变引用)可以并发进行,但读写操作不能同时进行,从而防止了数据竞争。
代码示例
- 正常运行示例
struct Data {
value: i32,
}
fn operate(data: &mut Data, read_only: &Data) {
data.value += 1;
let read_value = read_only.value;
println!("Read value: {}", read_value);
}
fn main() {
let mut data = Data { value: 10 };
operate(&mut data, &data);
}
在这个例子中,operate
函数接收一个可变引用 data
和一个不可变引用 read_only
。函数内部先对 data
进行写操作(修改 value
),然后通过不可变引用 read_only
进行读操作。由于写操作在前面,且读操作发生在写操作之后,并且整个操作在函数 operate
的作用域内,所以符合借用规则,代码可以正常编译运行。
- 违反借用规则编译失败示例
struct Data {
value: i32,
}
fn operate(data: &mut Data, read_only: &Data) {
let read_value = read_only.value;
data.value += 1;
println!("Read value: {}", read_value);
}
fn main() {
let mut data = Data { value: 10 };
operate(&mut data, &data);
}
在这个修改后的例子中,先通过不可变引用 read_only
读取数据,然后试图通过可变引用 data
修改数据。这违反了Rust的借用规则,因为在不可变借用 read_only
仍在作用域内时,就尝试进行可变借用的写操作,此时编译会失败,报错信息类似:
error[E0502]: cannot borrow `*data` as mutable because it is also borrowed as immutable
--> src/main.rs:8:13
|
7 | let read_value = read_only.value;
| --------------- immutable borrow occurs here
8 | data.value += 1;
| ^^^^^ mutable borrow occurs here
9 | println!("Read value: {}", read_value);
| -------- immutable borrow later used here
这样就展示了Rust借用机制如何防止数据竞争,违反规则时会导致编译失败。