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)$ |