RustArena

Copy vs Clone in Rust

The difference between Copy and Clone in Rust: implicit bitwise copies vs explicit .clone(), which types are Copy, and when to derive each.

Both Copy and Clone produce a duplicate of a value, but they work very differently.

Copy Clone
How it happens implicitly, on every assignment or call explicitly, when you write .clone()
What it does copies the bits on the stack whatever the type's clone method does (often a deep copy)
Cost always cheap can be expensive (allocates, copies heap data)
Old value afterwards still usable still usable
Examples i32, f64, bool, char, &T, (i32, i32), [u8; 4] String, Vec<T>, HashMap, Box<T>, plus every Copy type

Copy: values that are just bits

A type can be Copy only if duplicating its bytes produces a correct, independent value. An i32 qualifies: two copies of the number 5 never interfere. A String doesn't: its bytes are a pointer to heap memory, so a bitwise copy would give two owners of the same text, and a double free when both are dropped. That's why String moves instead.

Shared references &T are Copy (many readers are allowed), but &mut T is not (only one writer at a time).

Clone: an explicit, possibly expensive duplicate

.clone() asks a type to make a full, independent copy. For a String it allocates new heap memory and copies the text. Because it's explicit, you can see every place your code pays for a copy.

Deriving them for your own types

#[derive(Debug, Clone, Copy, PartialEq)]
struct Point {
    x: i32,
    y: i32,
}

Copy requires Clone (it's a supertrait), so you always derive both. You can only derive Copy if every field is Copy:

#[derive(Clone, Copy)]
struct Player {
    name: String,
    score: u32,
}

fn main() {}
error[E0204]: the trait `Copy` cannot be implemented for this type
 --> src/main.rs:2:8
  |
1 | #[derive(Clone, Copy)]
  |                 ---- in this derive macro expansion
2 | struct Player {
  |        ^^^^^^
3 |     name: String,
  |     ------------ this field does not implement `Copy`

Derive only Clone for such types. A type that implements Drop can't be Copy either.

When to derive Copy

Derive Copy for small value types: coordinates, colors, ids, money amounts, small enums like Direction. Code using them reads naturally (let p2 = p1;) and there's no performance cost.

Think twice before making a type Copy if it might later gain a String or Vec field: removing Copy then is a breaking change for every user of the type. For large structs, Copy can also hide expensive memcpys.

Common mistakes

Example

#[derive(Debug, Clone, Copy, PartialEq)]
struct Point {
    x: i32,
    y: i32,
}

#[derive(Debug, Clone)]
struct Player {
    name: String,
    pos: Point,
}

fn main() {
    let a = Point { x: 1, y: 2 };
    let mut b = a; // Copy: a is still usable
    b.x = 10;
    println!("{a:?} {b:?}");

    let p1 = Player { name: String::from("Ferris"), pos: a };
    let mut p2 = p1.clone(); // Clone: the String's text is copied too
    p2.name.push_str(" II");
    p2.pos.y += 5;
    println!("{} at {:?}", p1.name, p1.pos);
    println!("{} at {:?}", p2.name, p2.pos);
    println!("same position: {}", p1.pos == p2.pos);

    let nums = vec![1, 2, 3];
    let total: i32 = nums.iter().copied().sum(); // copied(): &i32 -> i32
    println!("{nums:?} total {total}");
}

Output:

Point { x: 1, y: 2 } Point { x: 10, y: 2 }
Ferris at Point { x: 1, y: 2 }
Ferris II at Point { x: 1, y: 7 }
same position: false
[1, 2, 3] total 6

Practice it