这个问题似乎暗示它只是一个实现细节(memcpy vs ??),但我找不到任何关于区别的明确描述。


当前回答

Clone是为任意复制而设计的:类型T的Clone实现可以执行创建新T所需的任意复杂操作。它是一个正常的trait(除了在前奏中),因此需要像正常trait一样使用,包括方法调用等。

Copy特征表示可以通过memcpy安全地复制的值:像重赋和按值传递参数给函数这样的事情总是memcpy,因此对于Copy类型,编译器理解它不需要考虑这些移动。

其他回答

主要的区别是克隆是显性的。隐式符号表示非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.

顺便说一下,每个拷贝类型也要求是克隆。然而,他们不需要做同样的事情!对于您自己的类型,.clone()可以是您选择的任意方法,而隐式复制总是会触发memcpy,而不是clone(&self)实现。

Clone是为任意复制而设计的:类型T的Clone实现可以执行创建新T所需的任意复杂操作。它是一个正常的trait(除了在前奏中),因此需要像正常trait一样使用,包括方法调用等。

Copy特征表示可以通过memcpy安全地复制的值:像重赋和按值传递参数给函数这样的事情总是memcpy,因此对于Copy类型,编译器理解它不需要考虑这些移动。

正如其他答案所涵盖的:

复制是隐式的、廉价的,并且不能重新实现(memcpy)。 克隆是显式的,可能是昂贵的,并且可以任意地重新实现。

在复制与克隆的讨论中,有时会忽略的是,它还会影响编译器如何使用移动和自动复制。例如:

#[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);
}

(生锈操场)

第一个例子(PointCloneAndCopy)在这里工作得很好,因为隐式复制,但第二个例子(PointCloneOnly)会在move后使用错误:

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

为了避免隐式移动,可以显式调用let p2 = p1.clone();。

这可能会引发一个问题:如何强制移动实现Copy特征的类型?

简单的回答:你不能/没有道理。

我觉得这个解释很有帮助:

在Rust中,一些简单的类型是“隐式可复制的”,当你分配它们或将它们作为参数传递时,接收者将获得一个副本,原始值保留在适当的位置。对于其他类型,必须通过实现Clone特征并调用Clone()方法显式地进行复制。

Clone特性定义了显式创建对象T的深度副本的能力。当我们为类型T调用Clone时,它会执行创建新T所需的所有任意复杂操作。

rust中的Copy特性定义了隐式复制对象的能力。Copy行为不可重载。它总是一个简单的位拷贝。这适用于具有固定大小且完全存储在堆栈上的类型。

参考:https://intmain.co/difference-between-copy-and-clone-trait-in-rust

就像这里写的。

复制是隐式发生的,例如作为赋值y = x的一部分。Copy的行为是不可重载的;它总是一个简单的位拷贝。

克隆是一个显式操作,x.clone()。Clone的实现可以提供安全复制值所需的任何特定于类型的行为。例如,Clone For String的实现需要在堆中复制指向字符串的缓冲区。简单的按位复制String值只会复制指针,导致一行中出现double free。因此,字符串是克隆而不是复制。

克隆是复制的一个超特性,所以任何是复制也必须实现克隆。如果一个类型是Copy,那么它的Clone实现只需要返回*self