Rust、Copy Trait在使用泛型时不能与类型一起使用



Rust不会编译以下内容:

#[derive(Copy, Clone)]
struct WhateverStruct<T> {
field : T
}
trait WhateverStructTrait<T> {
fn to(self) -> WhateverStruct<T>;
}
impl<T> WhateverStructTrait<T> for *mut WhateverStruct<T> {
fn to(self) -> WhateverStruct<T> {
unsafe {* self }
}
}
fn test() {
let x = WhateverStruct { field : 7u32 };
let _y = x;
let _z = x;
println!("Copying is fine");
}
fn main() {
test();
}

它抱怨不安全的{* self }部分说

*self具有类型WhateverStruct<T>,它不实现Copy特征

然而,它显然实现了复制特性。测试功能没有错误。如果将struct WhateverStruct<T> { field : T }更改为struct WhateverStruct { field : u32 },并从其余代码中删除<T>,则所有内容都可以编译和运行。所以Rust不喜欢普通的。

你可以在操场上看到:https://play.rust-lang.org/?version=stable&mode=调试&edition=2018&gist=5d5c3a00e6e0153ec286ce38f3a2d

这是个虫子吗?附近有工作吗?

对于任何泛型类型Foo<T>,当导出CopyClone时,特征总是具有分别绑定为CopyCloneT。有时,尽管您实际上并不需要T来实现结构作为一个整体的CopyClone的这些特征。

下面的结构就是一个例子。

#[derive(Copy, Clone)]
struct Foo<T> {
_marker: std::marker::PhantomData<T>,
}

如果我们查看派生生成的代码(cargo-expand适用于此目的(,我们会得到类似的东西

use std::prelude::v1::*;
#[macro_use]
extern crate std;
struct Foo<T> {
_marker: std::marker::PhantomData<T>,
}
#[automatically_derived]
#[allow(unused_qualifications)]
impl<T: ::core::marker::Copy> ::core::marker::Copy for Foo<T> {}
#[automatically_derived]
#[allow(unused_qualifications)]
impl<T: ::core::clone::Clone> ::core::clone::Clone for Foo<T> {
#[inline]
fn clone(&self) -> Foo<T> {
match *self {
Foo {
_marker: ref __self_0_0,
} => Foo {
_marker: ::core::clone::Clone::clone(&(*__self_0_0)),
},
}
}
}

只看Copy的实现(并稍微清理一下(,它就是

impl<T: Copy> Copy for Foo<T> {}

因此,即使Foo<T>不需要TCopy,它无论如何都会限制它。

在这些情况下,您只需要自己简单地实现CopyClone。只要结构的实际字段是Copy,就有一个相当琐碎的实现可以工作。

struct Foo<T> {
_marker: std::marker::PhantomData<T>,
}
impl<T> Copy for Foo<T> {}
impl<T> Clone for Foo<T> {
fn clone(&self) -> Self {
*self
}
}

相关内容

最新更新