Strings in Rust

Rust offers two main string types, &str and String, each optimized for different requirements.

Bernd Fischer

Bernd Fischer

13. Oct 2024 · 3 min read

Strings in Rust

The two string types in Rust are:

  • str (string slice)
  • String

1. The str Type

The type str (also known as a string slice) is a kind of immutable string. It is a collection of text data generally used through references (&str). Unlike String, str is a "borrowed" string, which means the memory location it points to is not managed by the str object itself.

Example: Using &str

fn main() {
    let text: &str = "Hello, Rust!";
    println!("{}", text);
}

Important properties of &str: - Immutable: A &str slice cannot be modified directly. - Borrowed: The memory a &str points to is not managed by &str, but by the owner of the original string. - Efficient: Since &str is immutable and does not allocate memory, it is very memory- and runtime-friendly.

String literals are &str

In Rust, string literals like "Hello, World!" are of type &str. They are embedded fixedly into the program and thus immutable.

fn main() {
    let literal = "I am an immutable string slice";  // `literal` ist vom Typ `&str`
    println!("{}", literal);
}

2. The String Type

The String type is an owned string stored on the heap. String is dynamic and allows creating and modifying strings at runtime.

Example: Creating and Modifying a String

fn main() {
    let mut my_string = String::from("Hello, ");
    my_string.push_str("Rust!");  // Modifiziert den String

    println!("{}", my_string);
}

Important properties of String: - Mutable: A String can be modified after creation. - Owned: The String type owns its memory and manages it automatically (e.g., automatic deallocation through Rust’s ownership model). - Heap-allocated: Memory is dynamically allocated on the heap, meaning the string’s size can grow or shrink at runtime.

Creating Strings

There are several ways to create a String in Rust:

1. With String::from

fn main() {
    let s = String::from("Hello, World!");
    println!("{}", s);
}

2. With to_string

fn main() {
    let s = "Hello".to_string();
    println!("{}", s);
}

3. Create an empty String

fn main() {
    let mut empty_string = String::new();  // Ein leerer String
    empty_string.push_str("Füge Text hinzu!");  // Text hinzufügen
    println!("{}", empty_string);
}

4. Conversion between &str and String

Because &str and String have different properties, sometimes it is necessary to convert between them.

4.1 From &str to String

There are multiple ways to convert a &str into a String:

1. With String::from

fn main() {
    let s: &str = "Hello, Rust!";
    let s_string = String::from(s);
    println!("{}", s_string);
}

2. With to_string

fn main() {
    let s: &str = "Hello, Rust!";
    let s_string = s.to_string();
    println!("{}", s_string);
}

4.2 From String to &str

A String can easily be converted to a &str by taking a reference to the String:

fn main() {
    let s: String = String::from("Hello, Rust!");
    let s_slice: &str = &s;  // Eine Referenz auf den `String`
    println!("{}", s_slice);
}

5. When to use &str and when String?

Use &str:

  • When you have immutable text, e.g., literals.
  • When you expect a string reference, such as in functions that only need access to the content without modifying it.

Use String:

  • When you have dynamic or mutable text.
  • When you want to create, modify, or extend text.