🎓 A1Learner
🔍

Rust Clone & Copy

Clone and Copy are the two traits that copy values in Rust. Clone copies only when code asks with .clone(), while Copy copies automatically on assignment.

Clone: a copy you ask for

Call .clone() and a full second value is built, heap data included. The original stays usable.

let pair = Pair(Box::new(1), Box::new(2));
let cloned = pair.clone();
println!("{:?} {:?}", pair, cloned);

Copy: a copy that happens by itself

For a Copy type, plain assignment copies the value — numbers, bool and char work this way too. Both names stay usable.

let unit = Marker;
let copied = unit;
println!("{:?} {:?}", unit, copied);

Copy needs Clone first

Copy is a subtrait of Clone: trait Copy: Clone. Derive both together — deriving Copy alone fails with error E0277.

#[derive(Debug, Clone, Copy)]
struct Marker;

A clone outlives its original

The clone holds its own data. So it still works after the original is dropped at the end of its block.

let kept = {
    let original = String::from("hello");
    original.clone()
};
println!("{kept}");

References copy; &mut only moves

A shared reference is Copy, so both copies can read the value. A &mut is never Copy — two live mutable borrows must never exist, so a &mut only ever moves.

let n = 5;
let r = &n;
let r2 = r;
println!("{} {}", r, r2);

Example

#[derive(Debug, Clone, Copy)]
struct Marker;
#[derive(Debug, Clone)]
struct Pair(Box<i32>, Box<i32>);
fn main() {
    let unit = Marker;
    let copied = unit;
    println!("unit still here: {:?}", unit);
    println!("copied: {:?}", copied);
    let pair = Pair(Box::new(1), Box::new(2));
    let cloned = pair.clone();
    println!("pair: {:?}", pair);
    println!("cloned: {:?}", cloned);
    println!("first values: {} and {}", pair.0, cloned.0);
}

Key points

  • A type may be Copy only under two conditions.
  • Every part of it must be Copy.
  • And it must own no resource.
  • So a struct holding a Box or a String can be Clone, never Copy.
  • Cloning a Copy type just copies the bits — for plain types, .clone() and plain assignment do the same thing
  • Copy is silent because it is always cheap: a few stack bits, nothing more.
  • A String moves on assignment, and an i32 copies.
  • Clone and Copy both make copies of a value.

In this example, Marker is an empty struct that derives Clone and Copy together. The line let copied = unit copies it silently. So unit still prints afterwards. Pair holds two Box values, so it can derive Clone but never Copy. pair.clone() builds a second Pair with its own boxes. Both print Pair(1, 2). The first values read 1 and 1. One trait copies when you ask. The other copies before you can ask.

Note

Clone is explicit because it can be costly — cloning a String copies every letter on the heap.

Try it Yourself

Edit the code, then press Run.

Running is simulated · Rust Playground

Exercise

A struct holds a Box<i32> field. Which pair of derives is allowed?