我有一个这样的结构
#[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)
如果msg
是i32
,则会进行编译。这样的基本看起来很奇怪
类型为String
不可复制。
答案 0 :(得分:11)
对我来说,看起来很奇怪,像字符串这样的基本类型是不可复制的。
Rust首先显式。
C程序员(尤其是Linus Torvald)对C ++的抱怨之一就是C ++中存在过多隐式复制,这隐藏了内存分配。再加上隐含的转换,它们真的可以在最意想不到的地方蔓延。
Rust的设计旨在揭示底层操作的复杂性。它会隐式执行一些转换(借用,从&T
到&Trait
),但这些转换便宜(通常是一段时间)。
这种显性表现在你在这里的两个特征中:
Clone
是指示 如何创建新实例,必须明确调用。大多数类型(但不是全部)都可以使用它复制。
Copy
是一个特定的编译器特征,表示开发人员希望激活该类型的隐式复制;它仅在浅拷贝等同于深拷贝时才可用,这确保了作为这些隐式拷贝的一部分不会发生内存分配
所以,为了确保你的评论:
String
是可复制的,请使用.clone()
String
不可隐式复制,因为这会导致非明显的内存分配发生答案 1 :(得分:3)
String
实际上是指向一些堆分配数据的指针,它的长度和容量。复制该信息会创建两个拥有的变量,这两个变量都指向相同的堆分配数据,这会破坏Rust的内存管理(您将遇到使用后免费问题)。
也就是说,你的结构不需要实现Copy
通过通道发送,它只需要Sized
,String
是(因为指针的大小)已知编译器)。在其中发送带有String
的结构或枚举应该是开箱即用的,而不必导出任何特征。