MST

星途 面试题库

面试题:Rust中函数调用时移动语义在简单类型上的体现

在Rust中,假设有一个函数 `fn take_number(num: i32) { }`,当我们在主函数中定义 `let num = 5; take_number(num);`,请详细描述这里移动语义是如何体现的?如果后续再尝试使用 `num` 会发生什么,为什么?
11.2万 热度难度
编程语言Rust

知识考点

AI 面试

面试题答案

一键面试
  1. 移动语义的体现
    • 在Rust中,当调用take_number(num);时,num的所有权被移动到了take_number函数中。因为i32是实现了Copy trait的类型,但这里的传递仍然触发了移动语义。take_number函数现在拥有了num的值,从内存角度看,num的值被“搬移”到了函数take_number的栈帧中(概念上)。这意味着num原本所在的栈空间中的值被拿走供take_number函数使用。
  2. 后续尝试使用num的情况及原因
    • 如果后续再尝试使用num,编译器会报错。例如:
    fn take_number(num: i32) { }
    fn main() {
        let num = 5;
        take_number(num);
        println!("{}", num); // 这行代码会报错
    }
    
    • 原因是Rust的所有权系统规定,一个值在同一时刻只能有一个所有者。当num的所有权被移动到take_number函数后,main函数中的num变量不再拥有其值的所有权。尝试使用一个已经失去所有权的变量会导致编译错误,错误信息类似于use of moved value: 'num',这是为了保证内存安全,防止悬空引用等问题。虽然i32类型实现了Copy,但默认传递仍然是移动语义,若要使用Copy语义,可以显式地复制值,如take_number(num.clone()); 后,num仍然可以在main函数后续使用。