huo*_*uon 100
Clone是为任意复制而设计的:Clone类型的实现T可以执行创建新操作所需的任意复杂操作T.这是一个正常的特征(除了在前奏中),因此需要像普通特征一样使用方法调用等.
该Copy特征表示可以通过安全地重复值memcpy:之类的东西调动和价值传递的参数传递给函数总是memcpys和因此对于Copy类型,编译明白它并不需要考虑的一个举动.
mdu*_*dup 69
主要区别在于克隆是明确的.隐式表示法意味着移动非Copy类型.
// u8 implements Copy
let x: u8 = 123;
let y = x;
// x can still be used
println!("x={}, y={}", x, y);
// Vec<u8> implements Clone, but not Copy
let v: Vec<u8> = vec![1, 2, 3];
let w = v.clone();
//let w = v // This would *move* the value, rendering v unusable.
Run Code Online (Sandbox Code Playgroud)
顺便说一句,每种Copy类型也是必需的Clone.但是,他们不需要做同样的事情!对于您自己的类型,.clone()可以是您选择的任意方法,而隐式复制将始终触发a memcpy,而不是clone(&self)实现.
blu*_*e10 24
正如其他答案所涵盖的那样:
Copy 是隐式的、廉价的,并且不能重新实现 (memcpy)。Clone 是明确的,可能很昂贵,并且可能会任意重新实现。有时在讨论Copyvs 时遗漏的Clone是它也会影响编译器如何使用移动与自动副本。例如:
#[derive(Debug, Clone, Copy)]
pub struct PointCloneAndCopy {
pub x: f64,
}
#[derive(Debug, Clone)]
pub struct PointCloneOnly {
pub x: f64,
}
fn test_copy_and_clone() {
let p1 = PointCloneAndCopy { x: 0. };
let p2 = p1; // because type has `Copy`, it gets copied automatically.
println!("{:?} {:?}", p1, p2);
}
fn test_clone_only() {
let p1 = PointCloneOnly { x: 0. };
let p2 = p1; // because type has no `Copy`, this is a move instead.
println!("{:?} {:?}", p1, p2);
}
Run Code Online (Sandbox Code Playgroud)
PointCloneAndCopy由于隐式复制,第一个示例 ( ) 在这里工作正常,但第二个示例 ( PointCloneOnly) 在移动后使用会出错:
error[E0382]: borrow of moved value: `p1`
--> src/lib.rs:20:27
|
18 | let p1 = PointCloneOnly { x: 0. };
| -- move occurs because `p1` has type `PointCloneOnly`, which does not implement the `Copy` trait
19 | let p2 = p1;
| -- value moved here
20 | println!("{:?} {:?}", p1, p2);
| ^^ value borrowed here after move
Run Code Online (Sandbox Code Playgroud)
为了避免隐式移动,我们可以显式调用let p2 = p1.clone();.
这可能会引发一个问题,即如何强制实现 Copy trait 的类型的移动?. 简短的回答:你不能/没有意义。