liveBook · Manning

String

As explained in Refactoring to Rust

A string type is a type whose values represent text and whose representation determines how text storage and allocation are managed.

Text is not always stored or used the same way. Rust’s two common string types make that difference visible: `String` owns a growable buffer, while `&str` is a read-only reference to existing string data. Choosing between them helps control when text is allocated and whether it can be changed. section 2.4 section 2.4.1

Use `String` when you need to own or grow text. It stores character data in a heap-allocated buffer with a length and a capacity. Adding text within the available capacity does not require a new buffer; exceeding capacity requires reallocation. For example, `let mut x = String::new(); x.push('.');` creates a mutable string and appends a dot. If the required size is known, `String::with_capacity(10_000_000)` reserves room before repeated pushes. section 2.4.1

Listing 2.18 Preallocating strings to aid performance
fn main() {
  let mut x = String::with_capacity(10_000_000);  #1

  for i in 0..10_000_000 {
    x.push('.');
  }

  println!("{}", x.len());
}

Compare the reserved capacity with the number of characters pushed: the example knows its target size before building the string. section 2.4.1

A `&str` holds a pointer to string data and its length; it does not own that data. It can refer to text in a `String`, another buffer, or a string literal. A literal can be referenced as `&'static str` because it is compiled into the program and remains available throughout its run. The `'static` notation describes how long that reference is valid; fuller lifetime rules can wait until they are needed. section 2.4

Pass text without taking ownership

Suppose an `Artwork` has a name and a function only needs to print it. Make the printing function accept `name: &str`, then pass it the name from a borrowed artwork. This lets the function read the text without taking the artwork. By contrast, passing an owned `Artwork` by value moves it: trying to pass that same value again produces a compiler error. section 2.1 section 2.4

Conversions bridge the two types. Call `.as_str()` to pass a `String` to a function expecting `&str`; call `.to_string()` when a string literal or reference must become an owned `String`. That is why assigning a literal to a struct field typed `String` uses a conversion rather than the literal alone. section 2.1 section 2.4.1

The storage choice also matters when crossing language boundaries. WebAssembly has no primitive string type, so a runtime must handle text passed to a module; WasmEdge supplies string arguments when running a module through its binary. A Rust `String` used inside a module does not make strings a WebAssembly primitive. section 10.2

How Refactoring to Rust covers it

How deep it goes
Explains representations, mutability, capacity, and conversions through code; defers fuller treatment of lifetimes.
Examples
Compares repeated Python concatenation with Rust pushes, preallocates a large buffer, and passes an artwork name as a reference.
What it assumes
Introduces Rust strings through literals and structs while using familiar Python concatenation as a comparison.
What you can do after
Apply it via Rust’s standard library: choose `String` or `&str`, reserve capacity, and convert between them.
How it connects
Connects strings to ownership, borrowing, lifetimes, heap allocation, and WebAssembly arguments.

Also explained in

Compare how 24 books explain string →

Related concepts

This explainer was generated by Manning's knowledge graph from the text of Refactoring to Rust. The section links point to the parts of the book it draws on.