MST

星途 面试题库

面试题:Rust中借用规则如何确保内存安全

请详细阐述Rust借用规则的具体内容,以及这些规则是怎样保证内存安全的。并通过一个简单的代码示例,说明在违反借用规则时会出现什么编译错误。
25.0万 热度难度
编程语言Rust

知识考点

AI 面试

面试题答案

一键面试

Rust借用规则具体内容

  1. 同一时间,一个值要么只能有一个可变引用,要么可以有多个不可变引用
    • 可变引用允许对数据进行修改,为了避免数据竞争(多个引用同时修改数据导致未定义行为),同一时刻只能存在一个可变引用。
    • 不可变引用允许多个同时存在,因为它们只读数据,不会产生数据竞争。
  2. 引用的生命周期必须小于或等于被借用值的生命周期
    • 引用指向的值在引用有效的期间必须一直存在,否则会出现悬垂引用(引用指向已释放的内存),导致内存安全问题。

如何保证内存安全

  1. 防止数据竞争:通过限制同一时间只有一个可变引用,确保不会有多个部分同时修改同一块数据,从而避免数据竞争这种未定义行为,保证内存安全。
  2. 防止悬垂引用:要求引用的生命周期短于或等于被借用值的生命周期,使得引用始终指向有效的内存,避免了引用到已释放内存的情况。

代码示例及违反规则的编译错误

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 进行可变借用,因为它已经被不可变借用了,违反了同一时间只能有一个可变引用或多个不可变引用的规则。