← Back to Rust Course | Chapter 5: Ownership | Lesson 3 of 6

Clone and Copy

clone() makes a real second copy of your data, while Copy types are so small Rust just duplicates them automatically.

Copy Types

Simple, fixed-size types like i32, f64, bool, and char implement the Copy trait, meaning assignment duplicates the value instead of moving it -- both variables remain independently usable.

Example: Copy Types

markup
fn main() {
    let a = 5;
    let b = a; // a is copied, not moved
    println!("a = {}, b = {}", a, b);
}

Cloning Non-Copy Types

Types like String and Vec do not implement Copy because copying them can be expensive. Calling .clone() explicitly performs a full deep copy, leaving both the original and the clone valid and independent.

Example: Cloning Non-Copy Types

markup
fn main() {
    let original = String::from("clone me");
    let cloned = original.clone();
    println!("original: {}, cloned: {}", original, cloned);
}

Deriving Copy and Clone on a Struct

A custom struct can opt into Copy semantics with #[derive(Copy, Clone)], but only if every field it contains is itself Copy. This makes small value-like structs behave like built-in numeric types.

Example: Deriving Copy and Clone on a Struct

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

fn main() {
    let p1 = Point { x: 1, y: 2 };
    let p2 = p1;
    println!("{:?} and {:?}", p1, p2);
}

Clone Is Explicit, Copy Is Implicit

Copy happens silently on assignment for eligible types, while .clone() always requires an explicit method call. This visible distinction helps readers spot potentially expensive deep-copy operations in the code.

Example: Clone Is Explicit, Copy Is Implicit

markup
#[derive(Clone, Debug)]
struct Config {
    name: String,
}

fn main() {
    let config1 = Config { name: String::from("prod") };
    let config2 = config1.clone();
    println!("{:?} vs {:?}", config1, config2);
}
Common Mistakes
  1. Calling .clone() on every value out of habit, even simple Copy types like integers that are duplicated automatically.
  2. Forgetting that .clone() on a large data structure can be expensive since it performs a real, full deep copy.
  3. Assuming a custom struct is automatically Copy -- it must explicitly derive both Copy and Clone and contain only Copy fields.
Chapter Summary
  • Copy types (like integers, floats, booleans, and chars) are duplicated automatically on assignment instead of moved.
  • .clone() explicitly creates a full, independent deep copy of a value, and can be called on any type that implements Clone.
  • A struct can derive Copy only if every one of its fields is also Copy.
  • Choosing between relying on Copy and calling .clone() is a performance and design decision, not just a syntax choice.
🔒

Chapter Quiz — Complete all 6 topics to unlock

0/6 topics done

Complete these topics first:

Login to run this code

C/C++/Java/PHP execution requires a free account. Your code is saved — you'll land right back in the editor after logging in.