Question
In Rust, what is the difference between Copy and Clone?
I found a discussion that makes it sound like the difference might only be an implementation detail, such as memcpy versus something else, but I cannot find a clear, explicit explanation of how these two traits differ in meaning and usage.
Short Answer
By the end of this page, you will understand how Copy and Clone differ in Rust, why they exist as separate traits, how they interact with ownership, and when to use each one. You will also see practical examples of values that are copied automatically versus values that must be cloned explicitly.
Concept
In Rust, Copy and Clone both relate to making duplicate values, but they mean different things.
Copymeans a value can be duplicated implicitly just by assigning it, passing it to a function, or returning it.Clonemeans a value can be duplicated explicitly by calling.clone().
The important difference is not just performance or implementation. The real difference is about ownership semantics and safety guarantees.
Copy
A type that implements Copy is so simple and safe to duplicate that Rust allows duplication automatically. When you assign it to another variable, the original is still usable.
Examples:
- integers like
i32 - floating-point values like
f64 boolchar- tuples of
Copytypes - references like
&T
These types do not need special cleanup logic when they go out of scope.
Clone
A type that implements Clone can also be duplicated, but Rust requires you to say so explicitly with .clone().
Examples:
StringVec<T>HashMap<K, V>
These types often own heap-allocated data. Duplicating them may require allocating new memory and copying the underlying contents.
Why separate traits?
Rust uses ownership to prevent memory errors. If every value were duplicated automatically, it would be too easy to accidentally make expensive copies or create confusing ownership behavior.
So Rust splits duplication into two levels:
- Cheap, always-safe implicit duplication:
Copy - Potentially more expensive or meaningful duplication:
Clone
Relationship between them
In Rust, Copy types must also implement Clone.
That means:
- every
Copytype is alsoClone - not every
Clonetype isCopy
This is because if a value can be copied implicitly, it must also be possible to duplicate it explicitly.
Ownership behavior
For non-Copy types, assignment usually moves ownership.
let s1 = String::from("hello");
let s2 = s1;
// s1 can no longer be used here
For Copy types, assignment copies the value.
let x = 5;
let y = x;
// x is still valid
println!("{} {}", x, y);
For Clone types, you can request a duplicate manually.
let s1 = String::from("hello");
let s2 = s1.clone();
println!("{} {}", s1, s2);
Why String is Clone but not Copy
A String contains owned heap memory. If Rust allowed it to be Copy, then simple assignment would silently duplicate heap data all the time, which could be expensive and surprising.
Instead, assignment moves the String, and .clone() makes a full duplicate when you really want one.
Why this matters in real programming
Understanding Copy vs Clone helps you:
- predict whether a value will move or stay usable
- avoid ownership errors
- write APIs that are efficient and clear
- prevent unnecessary allocations
- understand why some values need
.clone()and others do not
Mental Model
Think of Rust values as items you can hand to someone.
- A
Copyvalue is like handing out a photocopy of a small note. You still keep your original automatically. - A
Clonevalue is like owning a physical folder full of documents. If someone else needs their own folder, you must deliberately ask for a duplicate to be made. - A move is like handing over the only original folder. After that, you no longer have it.
This mental model explains why Rust treats small simple values differently from heap-owning values:
- small note → easy to duplicate automatically
- large folder → duplicate only when you ask
So the distinction is not just how bytes are copied in memory. It is about whether Rust allows duplication to happen silently as part of normal ownership flow.
Syntax and Examples
Basic syntax
Clone is used explicitly:
let a = String::from("hello");
let b = a.clone();
Copy happens implicitly on assignment:
let x = 10;
let y = x;
Example 1: Copy type
fn main() {
let a = 42;
let b = a;
println!("a = {}, b = {}", a, b);
}
i32 implements Copy, so assigning a to b duplicates the value automatically. Both variables are valid.
Step by Step Execution
Consider this example:
fn main() {
let s1 = String::from("rust");
let s2 = s1.clone();
let n1 = 7;
let n2 = n1;
println!("{} {}", s1, s2);
println!("{} {}", n1, n2);
}
Here is what happens step by step:
-
let s1 = String::from("rust");- A
Stringis created. s1owns its heap-allocated text.
- A
-
let s2 = s1.clone();- Rust calls the
Cloneimplementation forString. - A new heap allocation is made.
- The contents
"rust"are copied into the new allocation.
- Rust calls the
Real World Use Cases
Where Copy is used
Copy is common for small value-like data:
- numeric calculations
- coordinates and dimensions
- timestamps or counters
- flags and options
- lightweight IDs
Example:
#[derive(Copy, Clone)]
struct Size {
width: u32,
height: u32,
}
A type like Size behaves like plain data. Copying it is cheap and expected.
Where Clone is used
Clone is common for owned data structures:
- duplicating request payloads
- copying configuration values
- reusing strings across tasks
- creating independent collections for processing
- snapshotting application state
Example:
let config_name = String::from("production");
let backup_name = config_name.clone();
Real Codebase Usage
In real Rust projects, developers use Copy and Clone as part of API design.
Common patterns
Small domain types are often Copy
#[derive(Copy, Clone, Debug, PartialEq, Eq)]
enum Status {
Active,
Disabled,
}
Enums like this are cheap to duplicate and easy to pass around.
Owned data is usually Clone
#[derive(Clone, Debug)]
struct AppConfig {
app_name: String,
port: u16,
}
The String field means the struct should not be Copy, but Clone is useful when multiple parts of the program need similar config data.
Avoid cloning unless needed
Experienced Rust developers try not to call .clone() automatically everywhere. Instead, they often:
- borrow with
&T
Common Mistakes
Mistake 1: Thinking Copy and Clone only differ in speed
They differ in meaning, not just performance.
Copy= implicit duplication allowedClone= explicit duplication required
Even if a clone happens to be cheap, that does not automatically make the type suitable for Copy.
Mistake 2: Expecting assignment to duplicate a String
Broken example:
let a = String::from("hello");
let b = a;
println!("{}", a); // error
Why it fails:
Stringis moved, not copied.
Fix:
let a = String::from("hello");
= a.();
(, a, b);
Comparisons
| Concept | Copy | Clone |
|---|---|---|
| How duplication happens | Implicitly | Explicitly with .clone() |
| Assignment behavior | Duplicates value | Usually moves unless cloned |
| Typical cost | Cheap | May be cheap or expensive |
| Requires programmer intent | No | Yes |
| Good for heap-owning data | No | Yes |
Must also implement Clone | Yes | Not necessarily Copy |
Copy vs move
Cheat Sheet
Quick rules
Copy= implicit duplicationClone= explicit duplication with.clone()- All
Copytypes must also beClone - Not all
Clonetypes areCopy - Assignment of non-
Copyvalues usually moves ownership
Common Copy types
i32, u64, f32, bool, char, &T
Common Clone but not Copy types
String, Vec<T>, HashMap<K, V>
Basic examples
let x = 1;
let = x;
FAQ
Is Copy just a faster version of Clone?
No. The main difference is semantic: Copy happens implicitly, while Clone must be called explicitly. Performance is not the whole story.
Why does String implement Clone but not Copy?
Because String owns heap memory. Automatic copying on every assignment would be expensive and surprising, so Rust requires explicit cloning.
Can I implement Copy without Clone?
No. In Rust, a type that is Copy must also be Clone.
How do I know whether assignment moves or copies?
Check whether the type implements Copy. If it does, assignment copies. If it does not, assignment usually moves.
Should I call .clone() to fix ownership errors?
Sometimes, but not always. Many ownership errors are better solved by borrowing with references instead of cloning.
Can structs be ?
Mini Project
Description
Build a small Rust program that demonstrates the difference between moving, copying, and cloning values. This project is useful because it turns an abstract ownership rule into behavior you can observe directly in code.
Goal
Create a program that shows one Copy type being reused after assignment and one Clone-only type being duplicated explicitly.
Requirements
- Create one custom type that can derive
CopyandClone. - Create one custom type that contains a
Stringand derives onlyClone. - Show that assigning the
Copytype leaves the original usable. - Show that cloning the
Clone-only type creates two independent owned values. - Print results that make the difference visible.
Keep learning
Related questions
Accessing Cargo Package Metadata in Rust
Learn how to read Cargo package metadata like version, name, and authors in Rust using compile-time environment macros.
Default Function Arguments in Rust: What to Use Instead
Learn how Rust handles default function arguments, why they are not supported, and practical patterns to achieve similar behavior.
Fixing Rust "linker 'cc' not found" on Debian in WSL
Learn why Rust shows "linker 'cc' not found" on Debian in WSL and how to fix it by installing the required C build tools.