MST

星途 面试题库

面试题:Rust所有权模型中借用规则的具体内容是什么

请详细阐述Rust所有权模型里借用规则,包括但不限于同一时间内可变借用和不可变借用的限制,以及为什么要有这些规则。同时举例说明违反借用规则时编译器会给出怎样的错误提示。
23.4万 热度难度
编程语言Rust

知识考点

AI 面试

面试题答案

一键面试

Rust 所有权模型中的借用规则

  1. 不可变借用
    • 可以有多个不可变借用同时存在。例如:
fn main() {
    let s = String::from("hello");
    let r1 = &s;
    let r2 = &s;
    println!("{} {}", r1, r2);
}
  • 这是因为不可变借用只是读取数据,多个读取操作不会相互冲突。
  1. 可变借用
    • 同一时间内,只能有一个可变借用。例如:
fn main() {
    let mut s = String::from("hello");
    let r1 = &mut s;
    // 下面这行代码会报错,因为同一时间不能有第二个可变借用
    // let r2 = &mut s; 
    *r1 = String::from("world");
    println!("{}", r1);
}
  1. 不可变借用与可变借用的混合限制
    • 当存在可变借用时,不能同时存在不可变借用。例如:
fn main() {
    let mut s = String::from("hello");
    let r1 = &mut s;
    // 下面这行代码会报错,因为已经有了可变借用r1
    // let r2 = &s; 
    *r1 = String::from("world");
    println!("{}", r1);
}
  • 反过来,当存在不可变借用时,也不能创建可变借用。例如:
fn main() {
    let mut s = String::from("hello");
    let r1 = &s;
    // 下面这行代码会报错,因为已经有了不可变借用r1
    // let r2 = &mut s; 
    println!("{}", r1);
}

为什么要有这些规则

  1. 内存安全:这些规则确保在任何时刻,对于一块内存只有一个可变引用(可变借用),从而避免数据竞争。数据竞争会导致未定义行为,例如多个线程同时读写同一块内存且至少有一个是写操作,Rust通过借用规则在编译期就杜绝了这种情况。
  2. 可预测性:规则使得代码行为更具可预测性。开发人员可以明确知道在某一时刻数据是否可以被修改,提高了代码的可读性和维护性。

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

  1. 同一时间多个可变借用
    • 代码:
fn main() {
    let mut s = String::from("hello");
    let r1 = &mut s;
    let r2 = &mut s; 
}
  • 错误提示:
error[E0499]: cannot borrow `s` as mutable more than once at a time
 --> src/main.rs:4:14
  |
3 |     let r1 = &mut s;
  |                - first mutable borrow occurs here
4 |     let r2 = &mut s; 
  |              ^^^^^^ second mutable borrow occurs here
5 | }
  | - first borrow ends here
  1. 可变借用与不可变借用冲突
    • 代码:
fn main() {
    let mut s = String::from("hello");
    let r1 = &s;
    let r2 = &mut s; 
}
  • 错误提示:
error[E0502]: cannot borrow `s` as mutable because it is also borrowed as immutable
 --> src/main.rs:4:14
  |
3 |     let r1 = &s;
  |              - immutable borrow occurs here
4 |     let r2 = &mut s; 
  |              ^^^^^^ mutable borrow occurs here
5 | }
  | - immutable borrow ends here