You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

为何函数未获取Option<T>参数的所有权?变量移动规则疑问

为什么函数调用后原变量没被移动?

先看你的代码:

fn main() {
    let tested = Some(5);
    testoption(tested);
    println!("the tested is {}", tested.unwrap());
}

fn testoption(p: Option<i32>) {
    println!("the argument is {}", p.unwrap());
}

你觉得会触发移动但实际没有,核心原因是你的Option<i32>实现了Copy trait——实现这个trait的类型,在作为函数参数传递、赋值等场景下,会自动进行值复制,而不是转移所有权(移动),所以原变量依然可以正常使用。

哪些类型调用函数后不会被移动(即自动复制)?

  • 原生基本类型:比如i32、u64、f32、bool、char等,Rust默认给这些类型实现了Copy。
  • 由Copy类型组合的复合类型:
    • 元组:比如(i32, bool),只要所有元素都是Copy类型,元组自动实现Copy;
    • 结构体:如果结构体的所有字段都是Copy类型,并且你没有手动禁止,通过#[derive(Copy, Clone)]可以让结构体实现Copy;
    • 标准库泛型类型:比如Option<T>、Result<T, E>,只要泛型参数T(和E)是Copy类型,这些泛型类型也会自动实现Copy——你的例子里i32是Copy,所以Option<i32>也自动成了Copy类型。
  • 手动实现Copy的自定义类型:只要自定义类型的所有成员都实现了Copy,你就可以通过#[derive(Copy, Clone)]或者手动实现Copy trait,让它具备自动复制的特性。

反过来,如果类型没有实现Copy(比如String、Vec这类拥有堆内存的类型),传递给函数时就会触发移动,原变量之后就不能再被使用了——比如把你的例子改成Some(String::from("hello")),再运行就会编译报错,因为Option<String>没实现Copy,传递时移动了所有权。

内容的提问来源于stack exchange,提问作者passinger

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.26 00:37:22