关于Option<&T>实现Copy及map所有权差异的技术疑问
为什么Option和Option<&T>调用map的行为不同?
核心原因:Copy trait的条件性实现
你看到的Option<T>派生了Copy trait,但这个派生是条件性的——只有当泛型参数T本身实现了Copy时,Option<T>才会自动实现Copy。Rust的派生宏会根据泛型参数的trait实现情况,决定是否为容器类型生成对应的trait实现。
第一个示例报错的原因
let greet: Option<String> = Some("hi".to_string()); let mapped = greet.map(|e|e); dbg!(mapped); dbg!(greet); // 报错:use of moved value: `greet`
String类型没有实现Copy,所以Option<String>也没有Copytrait。map方法的签名是pub const fn map<U, F>(self, f: F) -> Option<U>,这里的self是所有权传递,调用greet.map()会把greet的所有权转移给方法内部,之后原变量greet就不再有效,所以后续访问会报错。
第二个示例正常运行的原因
let greet: Option<String> = Some("hi".to_string()); let mapped = greet.as_ref().map(|e|e); dbg!(mapped); dbg!(greet); // 正常运行
as_ref()方法把Option<String>转换成了Option<&String>,而引用类型&T默认实现了Copy。- 因为
&String是Copy的,所以Option<&String>自动满足了派生Copy的条件,拥有了Copytrait。 - 调用
map时,由于Option<&String>是Copy的,Rust会自动复制一份Option<&String>传递给map的self参数,原变量greet的所有权没有被转移,所以后续可以正常访问。
关于Option<&T>的Copy实现
你找不到明确的Option<&T>实现Copy的说明,是因为这个实现是通过派生宏的条件性生成完成的。当T实现Copy时,Option<T>就会自动实现Copy——而引用类型&T本身就实现了Copy,所以Option<&T>自然就有了Copy trait。
内容的提问来源于stack exchange,提问作者Theodora
相关产品推荐
相关产品推荐

