MST

星途 面试题库

面试题:Rust内存安全性三原则之借用规则理解

请详细阐述Rust中借用规则是如何保障内存安全的,结合示例代码说明在违反借用规则时会出现怎样的编译错误。
16.4万 热度难度
编程语言Rust

知识考点

AI 面试

面试题答案

一键面试

Rust借用规则保障内存安全的方式

  1. 同一作用域内不可变借用:在同一作用域内,可以有多个不可变借用。这是因为不可变借用只是读取数据,不会修改数据,所以多个读取操作不会产生冲突。例如:
fn main() {
    let s = String::from("hello");
    let r1 = &s;
    let r2 = &s;
    println!("r1: {}, r2: {}", r1, r2);
}
  1. 可变借用的独占性:同一时间内,对于一个资源只能有一个可变借用。这确保了在修改数据时,不会有其他地方同时访问或修改同一数据,避免数据竞争。例如:
fn main() {
    let mut s = String::from("hello");
    let r1 = &mut s;
    r1.push_str(", world");
    println!("{}", r1);
}
  1. 借用的生命周期:借用的生命周期必须足够短,不能超过被借用对象的生命周期。这防止了悬空指针的产生。例如:
fn main() {
    let r;
    {
        let s = String::from("hello");
        r = &s;
    }
    // println!("{}", r); // 这里会报错,因为s的生命周期结束,r成为悬空引用
}

违反借用规则时的编译错误

  1. 违反可变借用独占性
fn main() {
    let mut s = String::from("hello");
    let r1 = &mut s;
    let r2 = &mut s; // 编译错误:不能在r1借用期间创建r2的可变借用
    println!("r1: {}, r2: {}", r1, r2);
}

编译错误信息类似于:error[E0499]: cannot borrow s as mutable more than once at a time

  1. 借用生命周期问题
fn main() {
    let r;
    {
        let s = String::from("hello");
        r = &s;
    }
    println!("{}", r); // 编译错误:r引用了一个已离开作用域的变量s
}

编译错误信息类似于:error[E0597]: s does not live long enough