MST

星途 面试题库

面试题:Rust中共享引用和可变引用的规则及应用场景

请阐述Rust中共享引用(&T)和可变引用(&mut T)的规则,并且举例说明在哪些场景下你会优先选择使用共享引用,哪些场景下会使用可变引用。
11.3万 热度难度
编程语言Rust

知识考点

AI 面试

面试题答案

一键面试

Rust中共享引用(&T)和可变引用(&mut T)的规则

  1. 共享引用(&T)规则
    • 可以有多个共享引用同时指向同一个数据。
    • 共享引用只能读取数据,不能修改数据。这确保了在同一时间内,多个部分的代码可以安全地访问数据,而不用担心数据被意外修改,从而避免数据竞争问题。
  2. 可变引用(&mut T)规则
    • 在同一时间内,只能有一个可变引用指向特定的数据。
    • 可变引用允许对数据进行修改。这种限制保证了在任何时刻,只有一段代码可以修改数据,防止数据竞争。
    • 可变引用和共享引用不能同时存在。也就是说,当有一个可变引用时,不能有其他共享引用或可变引用指向同一数据;当有共享引用时,不能创建可变引用。

适用场景举例

  1. 优先选择共享引用的场景
    • 数据读取操作:当你只需要读取数据,例如遍历集合进行统计或者显示数据时,使用共享引用。例如:
fn sum_numbers(numbers: &[i32]) -> i32 {
    let mut sum = 0;
    for num in numbers {
        sum += num;
    }
    sum
}

在这个函数中,numbers 是共享引用,因为我们只是遍历并读取这个数组中的元素来计算总和,不需要修改数组。 - 多线程安全的数据访问:在多线程环境中,如果数据不需要被修改,使用共享引用可以安全地在多个线程间共享数据,因为共享引用不会引发数据竞争。 2. 优先选择可变引用的场景 - 数据修改操作:当你需要修改数据时,例如向数组中添加元素,或者修改结构体的字段。例如:

fn add_number(numbers: &mut Vec<i32>, num: i32) {
    numbers.push(num);
}

在这个函数中,numbers 是可变引用,因为我们需要修改 Vec,向其中添加新的元素。 - 原地算法:一些算法需要在原始数据上进行修改,而不是创建新的数据副本,这种情况下可变引用是必要的。例如排序算法通常会在原数组上进行排序:

fn sort_numbers(numbers: &mut [i32]) {
    numbers.sort();
}

这里 numbers 是可变引用,因为 sort 方法会修改数组的顺序。