我在Rust中有一个枚举,它有一个值需要一个String.这可以用这个简单的例子来证明:
#[derive(Clone, Copy)]
enum Simple {
Error(String),
Okay,
Foo([u32; 5]),
}
fn main() {
let x = Simple::Error(String::from("blah"));
let y = x.clone();
}
Run Code Online (Sandbox Code Playgroud)
Foo上面的枚举值代表我使用的大约10个其他枚举,它们采用可复制类型或它们的数组.编译器似乎没有抱怨它们,只有Error(String)这导致了这个:
error[E0204]: the trait `Copy` may not be implemented for this type
--> src/main.rs:1:17
|
1 | #[derive(Clone, Copy)]
| ^^^^
2 | enum Simple {
3 | Error(String),
| ------ this field does not implement `Copy`
Run Code Online (Sandbox Code Playgroud)
出于某种原因,String不可复制.我不懂.Clone对于其他类型的枚举,如何使用默认impl进行其余操作时,如何实现枚举?
Fra*_*gné 28
Copy 指定使按位复制创建有效实例而不使原始实例无效的类型.
但事实并非如此String,因为它String包含指向堆上字符串数据的指针,并假定它具有该数据的唯一所有权.删除a时String,它会释放堆上的数据.如果您已经对a进行了按位复制String,那么两个实例都会尝试释放相同的内存块,这是未定义的行为.
由于String未实现Copy,您enum无法实现Copy,因为编译器强制执行Copy仅由Copy数据成员组成的类型.
Clone仅提供标准clone方法,由每个实现者决定如何实现它.String实施Clone,所以你可以穿上#[derive(Clone)]你的enum.
我做了一些探索,看看手动实现枚举会是什么样子。我想出了这个,但请记住,您也可以#[derive(Clone)]按照其他地方的说明进行操作,编译器会为您完成此操作。
enum Simple {
Error(String),
Okay,
Foo([u32; 5]),
}
impl Clone for Simple {
fn clone(&self) -> Simple {
match self {
Error(a) => Error(a.to_string()),
Okay => Okay,
Foo(a) => Foo(a.clone()),
}
}
}
Run Code Online (Sandbox Code Playgroud)