如何为包含字符串的类型实现复制和克隆?

时间:2016-07-06 03:01:57

标签: rust

我在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();
}

上面的枚举值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`

由于某种原因,String不可复制。我不明白这一点。如何为只有一个类型的枚举实现Clone,而对其余类型使用默认impl时会出现问题?

2 个答案:

答案 0 :(得分:25)

复制

Copy指定使得按位复制创建有效实例而不会使原始实例无效的类型。

String不是这样,因为String包含指向堆上字符串数据的指针,并假定它具有该数据的唯一所有权。删除String时,它会释放堆上的数据。如果您已经对String进行了按位复制,则两个实例都会尝试释放相同的内存块,即未定义的行为

由于String未实现Copy您的enum无法实现Copy ,因为编译器强制执行Copy类型仅由Copy个数据成员组成。

克隆

Clone仅提供标准clone方法,由每个实现者决定如何实现它。 String确实实施了Clone,因此您可以#[derive(Clone)]放在enum上。

答案 1 :(得分:0)

我做了一些探索,以了解手动实现枚举是什么样子。我想到了这一点,但请记住,您也可以按照其他地方的说明进行#[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()),
        }
    }
}