Rust: str vs String
As a Rust newbie, I was confused by the different ways used to represent strings. The “References and Borrowing” chapter of the Rust book
uses three different types of string variables in the examples: String
, &String
and &str
.
Let’s start with the difference between str
and String
: String
is a growable, heap-allocated data structure whereas
str
is an immutable fixed-length string somewhere in memory 1.
String
If you’re a Java programmer, a Rust String
is
semantically equivalent to StringBuffer
(this was probably a factor in my confusion, as I’m so used to equating String
with immutable). As such, a String
maintains a length and a capacity whereas a str
only has a len()
method. As an example:
&str
You can only ever interact with str
as a borrowed type aka &str
. This is called a string slice, an immutable view
of a string. This is the preferred way to pass strings around, as we shall see.
&String
This is a reference to a String
, also called a borrowed type. This is nothing more than a pointer which you can pass
around without giving up ownership. Turns out a &String
can be coerced to a &str
:
In the above example, foo()
can take either string slices or
borrowed String
s, which is super convenient. As such, you almost never need to deal with &String
s.
The only real use case I can think of is if you want to pass a mutable reference to a function that
needs to modify the string:
Summary
Prefer &str
as a function parameter or if you want a read-only view of a string; String
when you want
to own and mutate a string.