PhantomDataCopy以令人惊讶的方式进行交互:
use std::marker::PhantomData;
#[derive(Copy, Clone)]
pub struct Seconds;
pub struct Meters;
#[derive(Copy, Clone)]
pub struct Val<T> {
pub v: PhantomData<T>
}
fn main() {
let v1: Val<Seconds> = Val {v: PhantomData};
let v2 = v1;
let v3 = v1;
let v4: Val<Meters> = Val {v: PhantomData};
let v5 = v4;
let v6 = v4;
}
Run Code Online (Sandbox Code Playgroud)
这失败如下:
src/main.rs:20:13: 20:15 error: use of moved value: `v4` [E0382]
src/main.rs:20 let v6 = v4;
^~
src/main.rs:19:13: 19:15 note: `v4` moved here because it has type `Val<Meters>`, which is moved by default
src/main.rs:19 let v5 = v4;
Run Code Online (Sandbox Code Playgroud)
我会认为获得Copy了Val<Meters>会给Val<Meters>拷贝语义.但显然,只有在Val类型参数T也实现的情况下才是真的Copy.我不明白为什么.
PhantomData总是实现Copy,无论其类型参数是否如此.总之和,如果PhantomData<Meters>没有实现Copy,我期望编译器抱怨说,它不能获得Copy的Val<Meters>.相反,编译器愉快地得出Copy了Val<Meters>,但它适用于移动语义.
这种行为是故意的吗?如果是这样,为什么?
我认为派生 Copy for
Val<Meters>会提供Val<Meters>复制语义。
但Copy不是为 派生的Val<Meters>,只是为它本身Val<T>所在的所有地方。TCopy
Github 上有几个未解决的问题,例如this one。我的印象是这不是故意的,而只是对derive当前工作方式的限制。
您可以通过手动为Cloneand编写一个全面的实现来解决这个问题Copy:
impl <T> Clone for Val<T> {
fn clone(&self) -> Val<T> {
Val {v: PhantomData}
}
}
impl <T> Copy for Val<T> {}
Run Code Online (Sandbox Code Playgroud)