正如标题所说,我说克隆用于在堆上复制,而复制用于在 Rust 中的堆栈上复制是否正确?
这基本上就是这篇文章所说的,但我怀疑它的正确性。
复制与克隆并不等同于堆栈与堆。Copy
和Clone
是特征,它们是类型的属性,而不是值所在位置的属性。与内存区域相比,它们与所有权的联系更紧密。
考虑这个例子,其中整数存储在堆上(通过Vec
),我从一个元素复制到另一个元素。这使用Copy
(因为没有显式.clone()
),但源和目标都在堆上:
let mut v = vec![0i32; 10];
v[0] = v[1];
考虑此示例,其中RefCell
存储在堆栈上,并使用Clone
获取另一个相同的。这两个元素都在堆栈上,但我必须使用.clone()
RefCell
没有实现Copy
。RefCell
也不使用任何堆分配:
let rc1 = RefCell::new(...);
let rc2 = rc1.clone();
实现Copy
的类型只是意味着它可以从一个内存位置按位复制到另一个内存位置,并且两个实例同样有效。
对于比较Copy
和Clone
,重要的是,在创建或销毁类型时,除了它所包含的就地数据之外,是否需要应用其他含义。拥有堆分配内存的所有权就是其中一种情况,因为您需要在所有者被销毁时取消分配该内存。像RefCell
那样保留额外的簿记记录也会使其失去实施Copy
的资格,因为数据的简单按位副本会产生不一致或无法使用的结果。管理外部资源(如文件句柄)是另一种情况,因为您必须与操作系统协调才能显式open()
和close()
文件。
Clone
特征提供了clone
复制方法。堆栈或堆取决于实现和类型要求。例如,如果要克隆String
,复制的值将在堆中分配。如果要克隆u8
类型的值,则会在堆栈上分配复制的值。Copy
特质完全符合Clone
特质的作用,但隐含着。
如果每个克隆的值都在堆中分配,我们就不需要分配器