# 8.7 Clone: explicit deep copies
> When you genuinely need two copies of a String, .clone() duplicates the heap data: how it works, what it costs, and when reaching for it is a mistake.
Source: https://learnrust.net/chapter-8/clone/
Twice now the compiler has ended an `E0382` with the same offer: "consider cloning the value if the performance cost is acceptable." This lesson takes the offer seriously.
## The honest copy
Sometimes you really do want two of a value. Not a handoff, not a loan: two independent `String`s, separate lives, separate fates. That's lesson [8.4](@/chapter-8/moves.md)'s "option two" (copy the heap block as well), and Rust does provide it; it just refuses to let `=` do it silently. The operation has a name you must write:
```rust
fn main() {
let original = String::from("hello");
let duplicate = original.clone();
println!("{original} {duplicate}");
}
```
```
hello hello
```
`.clone()` performs the **deep copy**: it asks the allocator for a new heap block, copies the text into it, and builds `duplicate` a handle of its own. Redraw lesson [8.2](@/chapter-8/the-stack-and-the-heap.md)'s diagram with two handles and *two blocks*, one each. Nothing is shared, so rule 2 (one owner at a time) is satisfied twice over: each block has its one owner, each owner drops its own block at the brace, and `original` remains alive and usable because nothing moved. The use-after-move program that opened lesson 8.4 becomes legal with eight typed characters, exactly as the compiler's diff suggested.
## If it's expensive, Rust makes you type it
Why a method call instead of just letting `=` do this? Because the cost is real: an allocator request plus copying every byte of the text, however many megabytes that turns out to be. Rust's position, which you've now seen from both sides, is a kind of pricing honesty:
- The **cheap** operation (moving a handle, a few bytes) is silent and default: `=`.
- The **expensive** operation (duplicating heap data) requires visible ink: `.clone()`.
You can audit a Rust function's memory behavior by reading it. Every costly duplication announces itself with the same eight characters; if you don't see `.clone()`, text isn't being copied.
{% callout(kind="author", title="Author's note") %}
This is my favorite "Rust deleted the problem" example in the course. C++ defaults the other way: assignment deep-copies silently, so innocent-looking code copies vectors and strings invisibly, and learncpp needs most of two chapters (14 and 22) to teach you to spot it, suppress it, and write the machinery that avoids it. Rust made the cheap thing the default and the expensive thing a visible word, and two chapters of another course's homework evaporate.
{% end %}
## Clone and Copy, side by side
The chapter's two duplication mechanisms, now that you've met both:
| | Copy (lesson [8.5](@/chapter-8/copy-types.md)) | Clone |
|---|---|---|
| Triggered by | Plain `=`, automatic | You write `.clone()` |
| Cost | Always trivial (copies the boxes) | Whatever the data weighs |
| Available on | Whole-in-the-box types only | Nearly everything, `String` included |
| In the diagram | Duplicates the box | Duplicates box *and* heap block |
(For completeness: Copy types have `.clone()` too, and on them it's just the same trivial box-copy. You'll never need to write `five.clone()`, but seeing it won't mean anything deep is happening.)
## The right uses, and the crutch
Clone is correct when two independent values is the actual requirement. You want to keep an original and mutate a variant; a value must go two places with two futures. Those clones aren't waste, they're the program's logic.
But there's a beginner pattern worth warning about by name, because every Rust learner passes through it. You write code, `E0382` appears, the compiler mentions `.clone()`, you type `.clone()`, the error disappears. Repeat until the program is confetti'd with clones that exist only to make errors go away. Each one is a real allocation and a real copy that your program's *meaning* never asked for. The give-and-take-back dance from lesson [8.6](@/chapter-8/ownership-and-functions.md) had the same flavor: a workaround for "I just want the function to *look* at my value," and you've known the real answer's name since that lesson. Lend it. Chapter 9 is one page-turn away, and most error-silencing clones are exactly the clones references make unnecessary.
{% callout(kind="best", title="Best practice") %}
Clone deliberately, not reflexively. Before typing `.clone()`, ask: does this program genuinely need two independent copies, or do I just need to *look at* the value from somewhere else? If it's the second, the answer is chapter 9's references, and the clone would be paying an allocation to avoid a lesson.
{% end %}
To close the loop, here's 8.4's forbidden program made legal both ways, with the difference spelled out:
```rust
fn main() {
// Way one: clone, because we genuinely want s1 alive afterwards
let s1 = String::from("hello");
let s2 = s1.clone();
println!("{s1} {s2}");
// Way two: restructure, because we only needed s1 *before* the move
let s3 = String::from("world");
println!("{s3}");
let s4 = s3;
println!("{s4}");
}
```
```
hello hello
world
world
```
Way one costs a heap block and buys two independent strings. Way two costs nothing: using the value *before* moving it often dissolves the conflict without any copy at all. Reordering beats cloning when reordering is possible; cloning is for when it isn't.
## Quiz time
**Question #1**
What does this print, and how many heap blocks were allocated for text over the program's lifetime?
```rust
fn main() {
let a = String::from("ping");
let b = a.clone();
let c = b.clone();
println!("{a} {b} {c}");
}
```
Show solution
```
ping ping ping
```
Three blocks: one from `String::from`, one per clone. Three owners, three blocks, three drops at the brace, all independent. (If this were chapter-9 code that merely needed to *read* `a` three times, zero clones would be required, which is the point of the best-practice box.)
**Question #2**
Clone, or restructure? For each, say which fix you'd use and why:
a)
```rust
fn main() {
let template = String::from("Dear ____,");
let letter = template;
println!("template was: {template}");
}
```
b)
```rust
fn main() {
let base = String::from("v1");
let mut experiment = base;
experiment.push_str("-test");
println!("{base} -> {experiment}");
}
```
Show solution
a) Restructure: print *before* the move (`println!` first, then `let letter = template;`). The program only needed `template` early; no second copy is required, so a clone would be pure waste.
b) Clone: `let mut experiment = base.clone();`. The program's actual logic wants two strings with different futures (the untouched `base` and the mutated `experiment`), so the deep copy is the meaning, not a workaround.
**Question #3**
A teammate's code contains `process(data.clone())` where `process`'s signature is `fn process(text: String) -> usize` and its body only calls `text.len()`. Critique the line: who is at fault, the call site or the signature, and what should each ideally be?
Show solution
The signature is the real culprit: a function that only *reads* the text has no business taking ownership, so `process` should take `&str` (lesson [8.6](@/chapter-8/ownership-and-functions.md)'s rule, and exactly what the compiler's "consider changing this parameter type to borrow instead" note keeps suggesting). The call site's `.clone()` is the symptom: a full copy of the text, allocated and duplicated, purely to feed a function that will read and drop it. Fix the signature and the clone disappears; until then, the give-it-back tuple would also work and would at least not copy. (Chapter 9 makes the good version one `&` long.)
That's all seven tools of the chapter. The summary collects them, the quiz makes you use them all at once, and then chapter 9 keeps a very large promise.