Cloning Data in Rust

In Rust, cloning creates a deep copy of data, especially for types that are stored on the heap like String and Vec. You use the clone() method to manually duplicate such values when ownership would otherwise be moved.

When a value in Rust is not a Copy type, assigning it or passing it to a function usually moves ownership. If you want to make a complete, independent copy of that value instead, you use cloning.

In this post, I will explain what cloning does, when to use it, and how it compares to shallow copying. If you have already read Copy vs. Move Semantics, this will feel like a natural next step.

What Is Cloning?

Cloning means creating a deep copy of data. This is different from simply copying a reference or assigning a value. In Rust, types like String and Vec store their data on the heap. Cloning them duplicates that data.

Example

let a = String::from("hello");
let b = a.clone();

println!("a: {}, b: {}", a, b);

Without clone(), the value would move from a to b, and a would become invalid. But cloning makes a full copy, so both variables are usable.

Why Clone Is Not Automatic

Rust makes you call clone() explicitly because:

  • Heap cloning can be expensive
  • You should only do it when necessary
  • It makes ownership clear in your code

This design helps avoid performance problems by making you think about memory usage.

Types That Implement Clone

Many types in Rust implement the Clone trait:

  • String
  • Vec<T>
  • Box<T>
  • HashMap
  • Custom structs (if all fields are Clone)

You can also make your own types Clone:

#[derive(Clone)]
struct User {
    name: String,
    age: u8,
}

Now you can write:

let u1 = User { name: String::from("Alice"), age: 30 };
let u2 = u1.clone();

This copies all fields, including the heap-allocated String inside.

Cloning vs Copying

FeatureCopyClone
TypeStack-only typesHeap or complex types
PerformanceFastSlower (heap allocation)
UsageAutomatic on assignmentManual: you call clone()
TraitCopy traitClone trait

Most primitive types like i32 and bool are Copy, so you do not need to clone them. Strings, vectors, and user-defined types usually need clone().

When to Clone

Use clone() when you need to keep using a value after moving it, or you want two independent copies of a complex type, or you want to return the same data from multiple branches or scopes.

Avoid overusing clone just to “make things work.” Borrowing with references is often a better and cheaper choice.

Common Mistake: Cloning in a Loop

let names = vec![String::from("Alice"), String::from("Bob")];

for name in names {
    println!("{}", name);
}

// println!("{:?}", names); // moved

Fix it with clone:

let names = vec![String::from("Alice"), String::from("Bob")];

for name in names.clone() {
    println!("{}", name);
}

println!("{:?}", names); // works now

But be careful as cloning a large vector can be expensive.

Summary

Cloning in Rust creates a deep copy of a value and its heap data. It is useful when you want to keep using a value after ownership would normally move. Rust requires you to use clone() explicitly to stay efficient and clear about memory usage.