Essential Standard Traits

Clone

The Clone trait defines explicit value duplication via .clone(), allowing a type to create an independent copy of itself that may perform arbitrary work such as heap allocation or reference-count increments.

Trait Definition

pub trait Clone: Sized {
    fn clone(&self) -> Self;

    fn clone_from(&mut self, source: &Self) {
        *self = source.clone()
    }
}

Unlike implicit bitwise copies (Copy), calling .clone() is always explicit in source code so that potentially expensive operations (such as duplicating a Vec<T> or String on the heap) remain visible.

Original: s1                     Cloned: s2 = s1.clone()
Stack           Heap             Stack           Heap
+---------+     +-------+        +---------+     +-------+
| ptr  ---+---> | "abc" |        | ptr  ---+---> | "abc" |
| len = 3 |     +-------+        | len = 3 |     +-------+
| cap = 3 |                      | cap = 3 |
+---------+                      +---------+

Deriving Clone

Applying #[derive(Clone)] generates an implementation that calls .clone() on every field in order. All fields of the struct or enum must implement Clone:

#[derive(Debug, Clone)]
struct Document {
    title: String,
    tags: Vec<String>,
}

fn main() {
    let original = Document {
        title: String::from("Architecture Spec"),
        tags: vec![String::from("rust"), String::from("systems")],
    };

    let mut duplicate = original.clone();
    duplicate.tags.push(String::from("v2"));

    println!("Original tags:  {:?}", original.tags);
    println!("Duplicate tags: {:?}", duplicate.tags);
}
Original tags:  ["rust", "systems"]
Duplicate tags: ["rust", "systems", "v2"]

Reusing Allocations with clone_from

The optional clone_from(&mut self, source: &Self) method overwrites an existing value in place. Standard heap containers such as String and Vec<T> override clone_from so that if self already has enough heap capacity, it reuses its existing buffer instead of allocating a new one:

fn main() {
    let mut buffer = String::with_capacity(64);
    let buffer_ptr_before = buffer.as_ptr();

    let source = String::from("reused allocation");
    buffer.clone_from(&source);

    assert_eq!(buffer, "reused allocation");
    assert_eq!(buffer.as_ptr(), buffer_ptr_before);
    println!("Buffer content: {buffer} (capacity: {})", buffer.capacity());
}
Buffer content: reused allocation (capacity: 64)

Cost of .clone() Across Standard Types

Type What .clone() Does Time Complexity
Primitive / Copy types (i32, bool, &T) Copies stack bytes $O(1)$
Rc<T> / Arc<T> Increments strong reference count; shares heap allocation $O(1)$
String / Vec<T> Allocates a new heap buffer and clones every element $O(n)$
HashMap<K, V> Allocates a new table and clones every key and value $O(n)$