MST

星途 面试题库

面试题:Rust中move语义下变量所有权转移机制

请详细阐述在Rust中,当一个变量被赋值给另一个变量时,move语义是如何导致所有权转移的?并举例说明。
32.8万 热度难度
编程语言Rust

知识考点

AI 面试

面试题答案

一键面试

在Rust中,每个值都有一个唯一的所有者,当一个变量被赋值给另一个变量时,会发生所有权的转移,这一过程遵循move语义。

  1. 基本原理

    • 当使用=将一个变量赋值给另一个变量时,如果被赋值的变量所指向的值是不可复制类型(例如StringVec等),Rust会把该值的所有权从源变量转移到目标变量。这意味着源变量不再拥有该值,不能再合法地使用它。
    • 这是Rust内存安全机制的核心部分,它确保在任何时刻,内存中的数据只有一个所有者,从而避免了诸如悬空指针或重复释放内存等问题。
  2. 举例说明

fn main() {
    let s1 = String::from("hello");
    let s2 = s1; // 这里发生了move语义,s1的所有权转移给了s2
    // println!("{}", s1); // 这一行会报错,因为s1不再拥有该字符串的所有权
    println!("{}", s2);
}

在上述代码中,s1创建了一个String类型的字符串。当执行let s2 = s1;时,s1的所有权被转移到了s2s1不再有效。如果尝试在let s2 = s1;之后使用s1,编译器会报错,提示s1已经被移动。

再看一个涉及函数调用的例子:

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

fn main() {
    let s = String::from("world");
    takes_ownership(s); // s的所有权转移到了takes_ownership函数中
    // println!("{}", s); // 这里会报错,因为s的所有权已经转移
}

在这个例子中,s作为参数传递给takes_ownership函数,s的所有权被转移到函数内部。函数结束时,函数内部的String对象被释放。同样,在函数调用之后再尝试使用s会导致编译错误,因为s的所有权已经不在当前作用域。