What are the differences between Rust's `String` and `str`?
Master System Design with Codemia
Enhance your system design skills with over 120 practice problems, detailed solutions, and hands-on exercises.
Introduction
Rust has two closely related string concepts that beginners often mix up: String and str. The short version is that String owns growable UTF-8 text on the heap, while str is the unsized string slice type that you usually use through &str.
String Owns the Data
String is an owned, heap-allocated, growable string type.
Important properties of String:
- it owns its bytes
- it can grow and shrink
- it is allocated on the heap
- you can mutate it if the binding is mutable
This makes String the right choice when your code needs to build or modify text dynamically.
str Is the String Slice Type
str is not usually used by itself. It is an unsized type, so you almost always encounter it as a reference: &str.
&str is a borrowed view into UTF-8 text that lives somewhere else. That text might come from:
- a string literal
- part of a
String - another borrowed string slice
The key point is that &str does not own the text. It only borrows it.
Why &str Is So Common
Rust APIs often prefer &str as input because it is flexible. A function that accepts &str can work with:
- string literals
- borrowed
Stringvalues - slices of existing strings
For example:
That is why &str is often the best parameter type when your function only needs to read text.
Converting Between Them
You can easily move between String and &str.
From String to &str:
From &str to String:
This is a normal part of Rust programming. The important thing is to choose ownership only when you really need it.
Mutability and Growth
One major practical difference is growth.
You can append to a String:
But you cannot append to &str, because a string slice is just a borrowed view into existing text. It has no authority to resize the underlying storage.
That means:
- use
Stringfor building or modifying text - use
&strfor reading or borrowing text
String Literals Are &'static str
Rust string literals are not String. They are &'static str.
That means the literal is a string slice pointing to statically stored program data. It is not heap-allocated and not growable.
This is one of the reasons beginners get confused. They write text in quotes and assume they created a String, but they actually created a string slice.
Performance and API Design
From an API design perspective, accepting &str is often better than accepting String because it avoids forcing callers to allocate when allocation is unnecessary.
Badly constrained:
Better for read-only input:
The second version is more ergonomic and more flexible because callers can pass either borrowed or owned text.
Common Pitfalls
The most common pitfall is thinking str and String differ only by syntax. They differ by ownership, mutability, and memory model.
Another mistake is writing functions that require String even though they only need read-only text. That creates unnecessary allocations and less flexible APIs.
A third issue is forgetting that string literals are &'static str, not String.
Finally, beginners often try to index strings like arrays of characters. In Rust, strings are UTF-8, so character boundaries and byte boundaries are not always the same thing.
Summary
- '
Stringis an owned, heap-allocated, growable UTF-8 string type.' - '
stris the string slice type, usually used as&str.' - Use
Stringwhen you need ownership or mutation. - Use
&strwhen you only need to borrow or read text. - Good Rust APIs often accept
&strbecause it is more flexible than requiringString.

