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

Dan*_*kov 7 rust

我有这样的结构

#[derive(Copy, Clone)]
enum Command {
    Quit,
    Error { msg: String },
}
Run Code Online (Sandbox Code Playgroud)

编译器抱怨它无法为其生成复制构造函数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)
Run Code Online (Sandbox Code Playgroud)

它编译如果msgi32.看起来很奇怪,这种基本类型String是不可复制的.

Mat*_* M. 11

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

Rust 首先是明确的.

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

而Rust的设计旨在揭示底层操作的复杂性.它含蓄地进行一些转换(借贷,从&T&Trait),但这些都是便宜(通常是固定时间).

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

  • Clone是关于如何创建新实例,必须显式调用.大多数类型(但不是全部)都可以使用它进行复制.

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

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

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


Mac*_*iej 9

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

也就是说,您的结构不需要实现Copy以通过通道发送,它只需要是Sized,即String(因为编译器知道指针的大小)。发送带有 a 的结构体或枚举String应该是开箱即用的,而无需派生任何特征。