TL;DR:
CopyandCloneare both about duplicating values, but they differ fundamentally.Copyis an implicit, bitwise duplication that happens automatically on assignment, no method call, no allocation, zero overhead. It is only available for simple stack types (integers, booleans, floats, references).Cloneis an explicit.clone()call that can perform arbitrary deep duplication, including heap allocation. If a type isCopy, assigning it does not move it. If it is onlyClone, assigning it moves it and you must call.clone()explicitly to duplicate.
What Is the Copy Trait?
Copy marks types that are safely duplicated by copying their bytes, assignment copies the value instead of moving it.
fn main() {
let x = 5i32; // i32 implements Copy
let y = x; // x is COPIED, not moved
println!("{x}"); // x is still valid; Copy types are never "moved away"
let a = 3.14f64;
let b = a; // both a and b are valid
println!("{a} {b}");
// References are Copy too
let s = String::from("hello");
let r1: &str = &s;
let r2 = r1; // r1 is copied (just the pointer+length); both valid
println!("{r1} {r2}");
}Copy types include: all integer types, f32/f64, bool, char, references (&T), and tuples/arrays of Copy types. A type cannot implement Copy if it contains a non-Copy field (like String or Vec).
What Is the Clone Trait?
Clone provides an explicit .clone() method that produces a duplicate, it may allocate, perform deep copies, or do anything the implementor defines.
fn main() {
let s1 = String::from("hello"); // String is NOT Copy
let s2 = s1.clone(); // explicit deep copy; allocates new heap memory
println!("{s1}"); // s1 still valid; not moved, cloned
println!("{s2}"); // independent copy
let v1 = vec![1, 2, 3];
let v2 = v1.clone(); // new Vec with its own heap allocation
println!("{:?}", v1);
println!("{:?}", v2);
}Clone is more general than Copy, every Copy type also implements Clone (trivially, by copying bytes), but not every Clone type implements Copy.
What Types Implement Copy?
A type implements Copy only if all its fields are Copy ; and it cannot own heap memory.
// Copy types; all stack-allocated, trivially copyable
let _ = 42i32; // integers
let _ = true; // bool
let _ = 'a'; // char
let _ = 3.14f64; // floats
let _ = (1i32, true); // tuple of Copy types
let _ = [1u8; 4]; // array of Copy type
// NOT Copy; owns heap data
let _ = String::from("hi"); // heap string
let _ = vec![1, 2, 3]; // heap vec
let _ = Box::new(5); // heap box
// Derive Copy (only works if all fields are Copy)
#[derive(Copy, Clone)]
struct Point { x: f64, y: f64 } // f64 is Copy; Point can be Copy
#[derive(Clone)] // NOT Copy; String is not Copy
struct User { name: String, age: u32 }Note: Clone must also be derived/implemented when implementing Copy, Copy is a subtrait of Clone.
How Do Copy and Clone Affect Function Calls?
Copy types are passed by value with no move, the caller retains the original. Non-Copy types are moved unless you pass a reference or .clone() first.
fn use_number(n: i32) {
println!("{n}");
}
fn use_string(s: String) {
println!("{s}");
}
fn main() {
let n = 42;
use_number(n);
println!("{n}"); // still valid; i32 is Copy
let s = String::from("hello");
// use_string(s);
// println!("{s}"); // COMPILE ERROR; s was moved
// Options:
use_string(s.clone()); // explicit clone; s is still valid
use_string(s); // or accept the move if you don't need s again
}Frequently Asked Questions
Only if the type is semantically a value type, coordinates, colors, small numeric types. Avoid Copy on types that are logically owned or expensive to copy, even if they could implement it, making them Copy leads to accidental duplications. Types like MutexGuard intentionally do not implement Copy to prevent being used after a lock release.
Copy requires that duplication is safe and cheap via bitwise copy. String owns heap memory, copying the bytes would create two Strings pointing to the same heap allocation, leading to a double-free when both are dropped. Only types that are entirely stack-resident (or that contain only raw pointers with manual memory management) can implement Copy.
It depends on the type. Cloning a String allocates a new heap buffer ; O(n) where n is the string length. Cloning an Arc<T> just increments an atomic counter ; O(1). Cloning a small struct with only Copy fields is equivalent to Copy. Always profile before optimizing clone calls.
Arc<T>, Rc<T>, String, Vec<T>, Box<T>, HashMap<K,V>, all types that own heap memory. Their .clone() may allocate, so Rust requires you to call it explicitly as a reminder that cost is involved.
Sources
- The Rust Book ; Stack-Only Data: Copy
- std::marker::Copy ; Rust Standard Library
- std::clone::Clone ; Rust Standard Library
Related Glossary Terms
- Ownership:
Copybypasses the move semantics of ownership - Trait:
CopyandCloneare traits derived with#[derive] - Struct: Structs can derive
Copyonly if all fields areCopy - Arc:
Arc::cloneis O(1): the idiomatic way to "copy" shared pointers

