为何Option<&T>调用.copied()方法后未被消耗?
问题解答
你的猜测方向是对的,但核心原因在于不可变引用&T本身就默认实现了Copy trait,这是Rust的内置规则,不需要为每个具体的&i32、&str等单独声明实现。
详细拆解:
copied的调用逻辑:copied的签名确实接收self,但如果self的类型实现了Copy,Rust会自动复制一份self的副本传递给函数,而非移动原变量。这意味着原变量不会被消耗,依然可以继续使用。引用类型的
Copy实现规则:
Rust中,所有不可变引用&T都自动实现了Copy——复制一个引用只是多了一个指向同一内存地址的指针,不会影响原引用指向的数据,完全符合Copytrait的语义。而可变引用&mut T则没有实现Copy(避免多个可变引用同时存在违反内存安全规则)。结合你的代码分析:
b的类型是Option<&i32>,由于&i32实现了Copy,通过你提到的 blanket impl:impl<T> Copy for Option<T> where T: Copy {}Option<&i32>也自动实现了Copy。- 当你调用
b.copied()时,Rust会复制b的副本传入函数,原b完全不受影响,所以后续打印b不会触发编译错误。
反向验证例子:
如果改成使用可变引用,由于&mut i32没有实现Copy,Option<&mut i32>也不会实现Copy,此时调用copied会移动原变量,后续使用b就会报错:
fn f1() { let mut a: i32 = 1; let b: Option<&mut i32> = Some(&mut a); let c: Option<i32> = b.copied(); println!("{:?}", b); // 编译错误:value borrowed here after move }
内容的提问来源于stack exchange,提问作者Joey
相关产品推荐
相关产品推荐

