MST

星途 面试题库

面试题:Rust借用机制如何防止简单数据竞争场景

假设有一个函数,它接收一个可变引用和一个不可变引用,对同一个数据结构进行操作。请描述在这种情况下,Rust借用机制是如何防止数据竞争的,并给出一个简单的代码示例,展示正常运行和违反借用规则时编译失败的情况。
32.4万 热度难度
编程语言Rust

知识考点

AI 面试

面试题答案

一键面试

Rust借用机制防止数据竞争原理

在Rust中,借用规则规定:

  1. 同一时间内,一个数据结构要么只能有一个可变引用(可变借用),要么可以有多个不可变引用(不可变借用),但不能同时存在可变引用和不可变引用。
  2. 引用的作用域必须在其所借用的数据结构的作用域之内。

这样的规则确保了在任何时刻,对数据结构的写操作(通过可变引用)是独占的,读操作(通过不可变引用)可以并发进行,但读写操作不能同时进行,从而防止了数据竞争。

代码示例

  1. 正常运行示例
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 的作用域内,所以符合借用规则,代码可以正常编译运行。

  1. 违反借用规则编译失败示例
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借用机制如何防止数据竞争,违反规则时会导致编译失败。