MST

星途 面试题库

面试题:Rust变量的可变性与所有权

在Rust中,解释变量的可变性(mutability)和所有权(ownership)概念,并举一个具体代码示例说明二者如何协同工作,同时说明如果违反所有权规则会出现什么编译错误。
33.8万 热度难度
编程语言Rust

知识考点

AI 面试

面试题答案

一键面试

变量的可变性(mutability)

在Rust中,默认情况下变量是不可变的。这意味着一旦绑定了一个值,就不能再改变它。使用mut关键字可以使变量可变,允许对其值进行修改。这有助于防止意外的变量修改,提高代码的稳定性和可维护性。

所有权(ownership)

所有权是Rust的核心特性,它通过一套规则来管理内存,无需垃圾回收器。每个值在Rust中都有一个所有者(变量),当所有者离开作用域时,值会被自动释放。所有权规则如下:

  1. 每个值都有一个所有者。
  2. 同一时刻,一个值只能有一个所有者。
  3. 当所有者离开作用域,这个值将被丢弃。

代码示例

fn main() {
    // 定义一个不可变变量
    let s1 = String::from("hello"); 
    // 尝试修改s1会导致编译错误,因为s1不可变
    // s1.push_str(", world"); 

    // 定义一个可变变量
    let mut s2 = String::from("goodbye"); 
    s2.push_str(", cruel world"); 

    // 所有权转移示例
    let s3 = s2; 
    // 这里s2不再有效,因为所有权转移到了s3
    // println!("{}", s2); // 这行代码会导致编译错误

    // 函数调用中的所有权转移
    takes_ownership(s3); 
    // 这里s3不再有效,因为所有权转移到了takes_ownership函数内部
    // println!("{}", s3); // 这行代码会导致编译错误

    let x = 5;
    makes_copy(x); 
    // 这里x仍然有效,因为i32类型实现了Copy trait,不会发生所有权转移
    println!("x is: {}", x); 
}

fn takes_ownership(some_string: String) {
    println!("{}", some_string);
}

fn makes_copy(some_integer: i32) {
    println!("{}", some_integer);
}

违反所有权规则的编译错误

  1. 双重释放错误:如果试图在所有权转移后继续使用原变量,编译器会报错。例如,在上述代码中,如果取消注释println!("{}", s2);,编译器会提示s2在这一作用域中已被移动。
  2. 悬垂指针错误:Rust通过所有权系统避免了悬垂指针的问题。因为当变量离开作用域时,其值会被自动释放,不存在指针指向无效内存的情况。如果代码试图创建类似悬垂指针的情况,编译器会拒绝编译。