实现 Copy
语义
- 条件:结构体所有成员都必须实现
Copy
特征。如果包含 Vec
这样的复杂类型,默认情况下 Vec
不实现 Copy
,因为 Vec
拥有堆上的数据,直接复制会导致多个实例指向同一块堆内存,引发所有权和内存安全问题。所以若结构体中有 Vec
,一般不能实现 Copy
。
- 实现方法:若结构体所有成员都实现
Copy
,只需在结构体定义前加上 #[derive(Copy, Clone)]
注解即可自动实现 Copy
和 Clone
特征。例如:
#[derive(Copy, Clone)]
struct SimpleStruct {
num: i32,
flag: bool
}
实现 Clone
语义
- 对于包含
Vec
的结构体:即使结构体中有非 Copy
类型(如 Vec
),也可以实现 Clone
。可以手动实现 Clone
特征,在 clone
方法中对每个成员进行适当的克隆操作。对于 Vec
,会在堆上分配新的内存并复制数据。例如:
struct ComplexStruct {
num: i32,
data: Vec<i32>
}
impl Clone for ComplexStruct {
fn clone(&self) -> Self {
ComplexStruct {
num: self.num,
data: self.data.clone()
}
}
}
- 使用
derive
注解:若结构体所有成员都实现 Clone
,也可使用 #[derive(Clone)]
注解自动实现 Clone
特征。
性能影响
- 内存分配:
Copy
:当实现 Copy
时,因为所有数据都在栈上,复制操作只是简单的栈上数据复制,不涉及堆内存分配。例如 SimpleStruct
的复制,只是将 num
和 flag
在栈上复制一份,效率很高。
Clone
:对于包含 Vec
的结构体,clone
操作会在堆上为新的 Vec
分配内存,并将原 Vec
中的数据复制到新分配的内存中。如 ComplexStruct
克隆时,data
成员的 Vec
会在堆上分配新内存,相比 Copy
涉及更多的内存操作。
- 复制时间:
Copy
:由于只是栈上数据复制,复制时间通常非常短,接近 CPU 指令级别的操作时间。
Clone
:除了栈上简单类型的复制,还需要进行堆内存分配和数据复制,所以 clone
操作的时间通常比 Copy
操作长,特别是当 Vec
中数据量较大时,堆内存分配和数据复制的开销会很明显。