如何定义包含String的可复制结构?

时间:2016-07-11 10:28:05

标签: rust

我有一个这样的结构

#[derive(Copy, Clone)]
enum Command {
    Quit,
    Error { msg: String },
}

编译器抱怨它无法为Error生成复制构造函数。

我需要使struct可复制以将通道传递给另一个线程。

error: the trait `Copy` may not be implemented for this type; variant `Error` does not implement `Copy` [E0205]
#[derive(Copy, Clone)]
^~~~~~~~~~~~~~~~~~~~~~
note: in this expansion of #[derive_Copy] (defined in src/main.rs)

如果msgi32,则会进行编译。这样的基本看起来很奇怪 类型为String不可复制。

2 个答案:

答案 0 :(得分:11)

  

对我来说,看起来很奇怪,像字符串这样的基本类型是不可复制的。

Rust首先显式

C程序员(尤其是Linus Torvald)对C ++的抱怨之一就是C ++中存在过多隐式复制,这隐藏了内存分配。再加上隐含的转换,它们真的可以在最意想不到的地方蔓延。

Rust的设计旨在揭示底层操作的复杂性。它会隐式执行一些转换(借用,从&T&Trait),但这些转换便宜(通常是一段时间)。

这种显性表现在你在这里的两个特征中:

  • Clone是指示 如何创建新实例,必须明确调用。大多数类型(但不是全部)都可以使用它复制。

  • Copy是一个特定的编译器特征,表示开发人员希望激活该类型的隐式复制;它仅在浅拷贝等同于深拷贝时才可用,这确保了作为这些隐式拷贝的一部分不会发生内存分配

所以,为了确保你的评论:

  • String是可复制的,请使用.clone()
  • String不可隐式复制,因为这会导致非明显的内存分配发生

答案 1 :(得分:3)

String实际上是指向一些堆分配数据的指针,它的长度和容量。复制该信息会创建两个拥有的变量,这两个变量都指向相同的堆分配数据,这会破坏Rust的内存管理(您将遇到使用后免费问题)。

也就是说,你的结构不需要实现Copy通过通道发送,它只需要SizedString是(因为指针的大小)已知编译器)。在其中发送带有String的结构或枚举应该是开箱即用的,而不必导出任何特征。