This issue seems to imply it's just an implementation detail (memcpy
vs ???), but I can't find any explicit description of the differences.

- 388,571
- 95
- 1,107
- 1,366

- 6,573
- 6
- 23
- 48
-
5Rust's source code has [relevant explanation](https://github.com/rust-lang/rust/blob/2e6eaceedeeda764056eb0e2134735793533770d/src/libcore/marker.rs#L272) – duan Mar 05 '20 at 10:13
-
2@duan here those comments are on the official docs site: [What is the difference between `Copy` and `Clone`](https://doc.rust-lang.org/std/marker/trait.Copy.html#whats-the-difference-between-copy-and-clone) and more on the very top of the docs page for [`Clone`](https://doc.rust-lang.org/std/clone/trait.Clone.html) – CircArgs Jan 05 '21 at 22:53
6 Answers
Clone
is designed for arbitrary duplications: a Clone
implementation for a type T
can do arbitrarily complicated operations required to create a new T
. It is a normal trait (other than being in the prelude), and so requires being used like a normal trait, with method calls, etc.
The Copy
trait represents values that can be safely duplicated via memcpy
: things like reassignments and passing an argument by-value to a function are always memcpy
s, and so for Copy
types, the compiler understands that it doesn't need to consider those a move.
-
15
-
36`Clone` opens the *possibility* that the type might do either a deep or shallow copy: "arbitrarily complicated". – poolie Sep 09 '16 at 23:03
-
2Fascinating, I thought `Copy` was just about allowing to make the `Clone` trait implicit. I'll leave here the reference as I'm probably not the only one puzzled. That exact question is answered in the manual now ( possibly not at the time of this question ): "Copies happen implicitly, for example as part of an assignment y = x. The behavior of Copy is not overloadable; it is always a simple bit-wise copy." https://doc.rust-lang.org/std/marker/trait.Copy.html#whats-the-difference-between-copy-and-clone – vincent Jul 30 '22 at 19:21
The main difference is that cloning is explicit. Implicit notation means move for a non-Copy
type.
// 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.
By the way, every Copy
type is also required to be Clone
. However, they are not required to do the same thing! For your own types, .clone()
can be an arbitrary method of your choice, whereas implicit copying will always trigger a memcpy
, not the clone(&self)
implementation.

- 7,889
- 3
- 32
- 34
-
2Cool! This clears up a secondary question I had regarding whether the Clone trait provides implicit copying. Turns out that question and this one were more related than I thought. Thanks! – user12341234 Jun 23 '15 at 20:42
-
In your first example, suppose you wanted `y` to get a moved `x`, not a copy of it, like with your last commented out example `w = v`. How would you specify that? – johnbakers May 04 '18 at 17:28
-
3You can't, and you don't, because `Copy` is meant to be implemented for "cheap" types, such as `u8` in the example. If you write a quite heavyweight type, for which you think a move is more efficient than a copy, make it _not_ impl `Copy`. Note that in the u8 case, you cannot possibly be more efficient with a move, since under the hood it would probably at least entail a pointer copy -- which is already as expensive as a u8 copy, so why bother. – mdup May 09 '18 at 10:55
-
Does this mean that the presence of the `Copy` trait has an impact on the implicit lifetime scopes of variables? If so I think that's noteworthy. – Brian Cain Jan 28 '19 at 03:38
As already covered by other answers:
Copy
is implicit, inexpensive, and cannot be re-implemented (memcpy).Clone
is explicit, may be expensive, and may be re-implement arbitrarily.
What is sometimes missing in the discussion of Copy
vs Clone
is that it also affects how the compiler uses moves vs automatic copies. For instance:
#[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);
}
The first example (PointCloneAndCopy
) works fine here because of the implicit copy, but the second example (PointCloneOnly
) would error with a use after 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
To avoid the implicit move, we could explicitly call let p2 = p1.clone();
.
This may raise the question of how to force a move of a type which implements the Copy trait?.
Short answer: You can't / doesn't make sense.

- 6,169
- 7
- 37
- 63

- 23,414
- 14
- 122
- 178
-
@Shepmaster I removed it although I find it much more readable because it contains the nice color coding of the Rust compiler and I specifically made sure that all the search relevant words are also contained in the text. – bluenote10 Jan 06 '20 at 17:20
-
-
@jangorecki I'm not sure. My understanding is that `Copy` simply does a memcpy of the raw struct in memory. This is as "shallow" as it can get, and should not be confused with "deep copying". The cheapest possible `Clone` that doesn't lose information would basically have to emulate a memcpy. Perhaps a `Clone` can be cheaper e.g. if it doesn't copy all fields though. – bluenote10 Jan 13 '21 at 21:28
As written here.
Copies happen implicitly, for example as part of an assignment
y = x
. The behavior ofCopy
is not overloadable; it is always a simple bit-wise copy.
Cloning is an explicit action,
x.clone()
. The implementation ofClone
can provide any type-specific behavior necessary to duplicate values safely. For example, the implementation ofClone
forString
needs to copy the pointed-to string buffer in the heap. A simple bitwise copy ofString
values would merely copy the pointer, leading to a double free down the line. For this reason,String
isClone
but notCopy
.
Clone
is a supertrait ofCopy
, so everything which isCopy
must also implementClone
. If a type isCopy
then itsClone
implementation only needs to return*self

- 1,988
- 2
- 23
- 37
IMHO, the intention is all your need
- both can be used to avoid borrow and lifetime annotation or smart pointer
- copy means copy semantics here, or means the value is going to be treated like in Java or JS language, this implies the value is somehow primitive or cheap to copy
- clone let you decide how deep the duplication is enough and you have to explicitly write
.clone
, which means it is already handled

- 1,651
- 1
- 12
- 17
I found this explanation very helpful:
In Rust, some simple types are “implicitly copyable” and when you assign them or pass them as arguments, the receiver will get a copy, leaving the original value in place. For other types, copies must be made explicitly, by implementing the Clone
trait and calling the clone()
method.
The Clone
trait defines the ability to explicitly create a deep copy of an object T. When we call Clone
for type T, it does all the arbitrarily complicated operations required to create a new T.
The Copy
trait in rust defines the ability to implicitly copy an object. The behavior Copy
is not overloadable. It is always a simple bitwise copy. This is available for the types that have a fixed size and are stored entirely on the stack.
Reference: https://intmain.co/difference-between-copy-and-clone-trait-in-rust

- 40
- 6