What are the differences between Rust's `String` and `str`?

rust, string

Solution

`String` is the dynamic heap string type, like `Vec`: use it when you need to own or modify your string data.

`str` is an immutable1 sequence of UTF-8 bytes of dynamic length somewhere in memory. Since the size is unknown, one can only handle it behind a pointer. This means that `str` most commonly2 appears as `&str`: a reference to some UTF-8 data, normally called a "string slice" or just a "slice". A slice is just a view onto some data, and that data can be anywhere, e.g.

In static storage: a string literal `"foo"` is a `&'static str`. The data is hardcoded into the executable and loaded into memory when the program runs.

Inside a heap allocated `String`: `String` dereferences to a `&str` view of the `String`'s data.

On the stack: e.g. the following creates a stack-allocated byte array, and then gets a view of that data as a `&str`:

use std::str;

let x: [u8; 3] = [b'a', b'b', b'c'];
let stack_str: &str = str::from_utf8(&x).unwrap();

In summary, use `String` if you need owned string data (like passing strings to other threads, or building them at runtime), and use `&str` if you only need a view of a string.

This is identical to the relationship between a vector `Vec<T>` and a slice `&[T]`, and is similar to the relationship between by-value `T` and by-reference `&T` for general types.

1 A `str` is fixed-length; you cannot write bytes beyond the end, or leave trailing invalid bytes. Since UTF-8 is a variable-width encoding, this effectively forces all `str`s to be immutable in many cases. In general, mutation requires writing more or fewer bytes than there were before (e.g. replacing an `a` (1 byte) with an `ä` (2+ bytes) would require making more room in the `str`). There are specific methods that can modify a `&mut str` in place, mostly those that handle only ASCII characters, like `make_ascii_uppercase`.

2 Dynamically sized types allow things like `Rc<str>` for a sequence of reference counted UTF-8 bytes since Rust 1.2. Rust 1.21 allows easily creating these types.

Problem

Why does Rust have both `String` and `str`? What are the differences between them, and when should one be used over the other? Is one of them getting deprecated?

Original source