Question
In Rust, what is the difference between clone() and to_owned()?
Clone is a trait that provides the clone method (and clone_from). Some types and traits, such as string slices and collection-related abstractions, also provide a to_owned() method. Why would a type need both methods, and how do they differ?
Consider this Rust example:
fn main() {
test_clone();
test_to_owned();
}
fn test_clone() {
let s1: &'static str = "I am static";
let s2 = "I am boxed and owned".to_string();
let c1 = s1.clone();
let c2 = s2.clone();
println!("{:?}", c1);
println!("{:?}", c2);
println!("{:?}", c1 == s1);
println!("{:?}", c2 == s2);
}
fn test_to_owned() {
let s1: &'static str = "I am static";
let s2 = "I am boxed and owned".to_string();
let c1 = s1.to_owned();
let c2 = s2.to_owned();
println!("{:?}", c1);
println!("{:?}", c2);
println!("{:?}", c1 == s1); // Why does this fail to compile?
println!("{:?}", c2 == s2);
}
The key confusion is this: clone() works for both values, but to_owned() changes the behavior for &str. Why does the first example compile while the second produces a type mismatch?
Short Answer
By the end of this page, you will understand that clone() duplicates a value without changing its type, while to_owned() converts borrowed data into its owned version. In Rust, this difference matters most for types like &str, where clone() returns another &str, but to_owned() returns a String.
Concept
clone() and to_owned() are related, but they solve different problems.
clone()
clone() comes from the Clone trait.
Its job is simple:
- make a duplicate of a value
- keep the same type
Examples:
- cloning a
Stringgives anotherString - cloning a
Vec<T>gives anotherVec<T> - cloning a
&strgives another&str
That last one is important: a string slice &str is a borrowed reference, not an owned string buffer. Cloning it does not allocate new string storage. It just copies the reference.
to_owned()
to_owned() is about converting data into an owned form.
Its job is:
Mental Model
Think of borrowed and owned data like reading a book.
- A borrowed value is like borrowing a library book.
- An owned value is like buying your own copy.
Now compare the methods:
-
clone()means: make another copy of whatever you currently have.- If you currently have a library card pointing to a book (
&str), cloning just copies the card. - You still do not own the book.
- If you currently have a library card pointing to a book (
-
to_owned()means: get your own personal copy.- If you borrowed the book (
&str),to_owned()buys a copy (String). - If you already owned the book (
String), it can make another owned copy.
- If you borrowed the book (
So for &str:
clone()-> another borrowed&strto_owned()-> an ownedString
That is why the types differ.
Syntax and Examples
Core syntax
let a = value.clone();
let b = value.to_owned();
The important question is: what type is value?
Example 1: &str
fn main() {
let s: &str = "hello";
let a = s.clone();
let b = s.to_owned();
// a: &str
// b: String
println!("{}", a);
println!("{}", b);
}
Explanation:
s.clone()returns another&strs.to_owned()returns aString
Step by Step Execution
Consider this small example:
fn main() {
let s: &str = "rust";
let a = s.clone();
let b = s.to_owned();
println!("{}", a);
println!("{}", b);
}
Step by step
1. Create s
let s: &str = "rust";
sis a string slice- it points to string data
- it does not own that data
2. Clone s
let a = s.clone();
clone()preserves the type
Real World Use Cases
When to use clone()
Use clone() when you want another value of the same type.
Common examples:
- duplicate a
Stringyou already own - copy a
Vec<T>before modifying one version - duplicate configuration data stored in an owned struct
- copy an
Arc<T>orRc<T>handle
let name = String::from("Alice");
let backup = name.clone();
When to use to_owned()
Use to_owned() when you have borrowed data but need to own it.
Common examples:
- convert
&strinput intoStringfor storage - convert a slice
&[T]into
Real Codebase Usage
In real projects, developers often use these methods as part of broader ownership patterns.
Pattern: accept borrowed, store owned
This is one of the most common Rust API designs.
struct Config {
host: String,
}
impl Config {
fn new(host: &str) -> Self {
Self {
host: host.to_owned(),
}
}
}
Why this is good:
- callers can pass
&stror string literals easily - the struct owns its data safely
Pattern: clone owned state before mutation
let original = String::from("draft");
let editable = original.clone();
Used when:
- you need a backup
- you want to preserve the original value
- ownership rules prevent moving the original
Pattern: guard clauses with borrowed input
Common Mistakes
1. Assuming clone() always makes a deep owned copy
Broken assumption:
let s: &str = "hello";
let c = s.clone();
Many beginners expect c to be a String. It is not.
sis&strcis also&str
Fix
Use to_owned() or to_string() when you need ownership.
let s: &str = "hello";
let owned = s.to_owned(); // String
2. Forgetting that to_owned() may change the type
Comparisons
| Method | Main purpose | Keeps same type? | Can convert borrowed to owned? | Example on &str | Example on String |
|---|---|---|---|---|---|
clone() | Duplicate a value | Yes | No | &str -> &str | String -> String |
to_owned() | Produce an owned version | Not always | Yes | &str -> String | String -> String |
to_string() |
Cheat Sheet
Quick rules
clone()returns the same type.to_owned()returns an owned version.- For borrowed data,
to_owned()often allocates. - For already owned data,
to_owned()often behaves similarly toclone().
Common examples
let s: &str = "abc";
let a = s.clone(); // &str
let b = s.to_owned(); // String
let s = String::from("abc");
let a = s.clone(); // String
let b = s.to_owned(); // String
FAQ
Why does clone() on &str not create a String?
Because clone() preserves the original type. A &str cloned value is still a &str.
Is to_owned() the same as clone() for String?
In practice, both produce a new String. The conceptual difference is that to_owned() means “give me an owned version,” while clone() means “duplicate this exact type.”
Should I use to_owned() or to_string() for &str?
Both can produce a String. For borrowed-to-owned conversion, to_owned() communicates intent more clearly.
Does to_owned() always allocate memory?
Not always in every possible type, but for common borrowed types like and slices, it creates owned data and therefore allocates.
Mini Project
Description
Build a small Rust program that accepts borrowed text and stores it inside an owned struct. This demonstrates why to_owned() exists and how it differs from clone() on borrowed string slices.
Goal
Create a User struct that stores a name as String, and write functions that show the difference between copying a borrowed &str and converting it into owned data.
Requirements
- Define a
Userstruct with aname: Stringfield. - Write one function that uses
clone()on a&strand prints the result type behavior. - Write another function that uses
to_owned()on a&strand stores it in aUser. - Show that a
Stringcan be duplicated with eitherclone()orto_owned().
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.
Associated Types vs Generic Type Parameters in Rust: When to Use Each
Learn when to use associated types vs generic parameters in Rust traits, with clear rules, examples, and practical API design advice.
Can a Struct Extend Another Struct in Rust? Composition vs Inheritance
Learn how Rust handles struct reuse without inheritance, using composition, traits, and wrapper structs with practical examples.