MST

星途 面试题库

面试题:Rust移动语义中所有权转移的场景举例

请举例说明在Rust中,哪些常见的代码场景会触发移动语义导致所有权的转移,并解释其原理。
39.9万 热度难度
编程语言Rust

知识考点

AI 面试

面试题答案

一键面试

1. 函数参数传递

  • 代码示例
fn take_ownership(s: String) {
    println!("I got ownership of: {}", s);
}

fn main() {
    let s = String::from("hello");
    take_ownership(s);
    // 这里如果再使用 s 会报错,因为所有权已转移给 take_ownership 函数
    // println!("{}", s); // 这行会导致编译错误
}
  • 原理:当把一个具有所有权的值(如 String)作为参数传递给函数时,所有权会转移到函数中。这是因为 Rust 的所有权系统规定,同一时刻只能有一个所有者。在这个例子中,smain 函数中创建,当传递给 take_ownership 函数时,take_ownership 函数成为 s 的新所有者。函数结束后,s 会在 take_ownership 函数的作用域结束时被释放。

2. 函数返回值

  • 代码示例
fn give_ownership() -> String {
    let s = String::from("world");
    s
}

fn main() {
    let new_s = give_ownership();
    println!("I got: {}", new_s);
}
  • 原理:函数返回值时,返回值的所有权从函数转移到调用者。在 give_ownership 函数中,s 被创建,当函数返回 s 时,所有权转移给 main 函数中的 new_s。这样,sgive_ownership 函数结束后不会被释放,而是由 new_s 继续拥有并管理其生命周期。

3. 变量赋值

  • 代码示例
fn main() {
    let s1 = String::from("rust");
    let s2 = s1;
    // 这里如果再使用 s1 会报错,因为所有权已转移给 s2
    // println!("{}", s1); // 这行会导致编译错误
    println!("{}", s2);
}
  • 原理:当一个具有所有权的变量赋值给另一个变量时,所有权会发生转移。在这个例子中,s1 创建后拥有字符串 rust 的所有权,当执行 let s2 = s1; 时,s1 的所有权转移给 s2s1 不再拥有该字符串的所有权,此时 s1 进入无效状态,不能再被使用。这保证了内存不会被重复释放,因为只有最后拥有所有权的变量在其作用域结束时才会释放内存。