Rust's strings
Another day, another expected `&str`, found struct `String`
error somewhere in my code. Since it's Sunday, I can take a few minutes to look into rust's strings (again) and jolt down some notes for future me.
&str
and String
The two main types used to store human readable strings in rust are &str
and String
. They are pretty well explained in the Rust By Example book, but basically:
&str
is a slice type made up of a pointer to some bytes (encoding a valid UTF-8 string) and the associated length. This is the type of string literals in code, namely&'static str
.String
is a custom type (i.e. astruct
) which allows for manipulation of a human readable string allocated on the heap. It can be thought of as aVec<u8>
.
Converting from one to another is easily possible as
- Going from
&str
toString
can be done with theString::from
function. - Going from
String
to&str
can be done by simply dereferencing aString
object.
String
dereferencing
String
implements Deref<Target = str>
, meaning that through the power of Deref
coercion a &String
reference can be used in places where a &str
is expected. This converstion happens automatically when references are passed to types which implement the appropiate Deref
trait.
Automatic reference level reduction
In addition, due to how Deref
coercion works, the compiler can also automatically remove reference levels in certain places. For example, the following code would work as normal (see rust playground):
fn test(a: &str) {
println!("{}", a)
}
fn main() {
let s: &str = "Hello world!";
test(s);
test(&s);
test(&&s);
test(&&&s);
// and so on...
}