M Logo
๐Ÿ“ Rust for Beginners ยท Part 9 of 22

Rust Slices and String vs &str Explained

November 10, 2026

Welcome to episode 9 of Rust for Beginners, a series for complete beginners (no programming experience needed). In the last video, we learned about references. Today, we'll learn about a special kind of reference, the slice, and finally answer: what's the difference between String and ampersand str? Every code block below is the exact code from the video, ready to copy.

1. New project

Let's create a new project called slices, and open it in VS Code.

bash
cargo new slices
cd slices

2. Slice

A slice is a reference to part of something. Ampersand text, zero dot dot five, borrows the first five bytes: hello.

src/main.rs:

rust
fn main() {
    let text = String::from("hello world");

    let hello = &text[0..5];
    let world = &text[6..11];
    println!("{hello} | {world}");

    println!("{} | {}", &text[..5], &text[6..]);
}

Output: hello | world / hello | world

3. Range

The start is included, the end is not. Six dot dot eleven gives us world.

4. Short forms

We can leave out the start to begin at zero, or the end to go to the very end.

5. Run A

Let's run it.

bash
cargo run

6. first_word

Slices are great as return values. first word goes through the text, and when it finds a space, it returns the slice before it. char indices gives each character together with its position.

rust
fn main() {
    let text = String::from("hello world");
    let word = first_word(&text);
    println!("First word: {word}");
}

fn first_word(s: &str) -> &str {
    for (i, c) in s.char_indices() {
        if c == ' ' {
            return &s[..i];
        }
    }
    s
}

Output: First word: hello

Stage B2 โ€“ let mut text, and text.clear(); after the call

rust
fn main() {
    let mut text = String::from("hello world");
    let word = first_word(&text);
    text.clear();
    println!("First word: {word}");
}

Error:

text
error[E0502]: cannot borrow `text` as mutable because it is also borrowed as immutable
 --> src/main.rs:4:5
  |
3 |     let word = first_word(&text);
  |                           ----- immutable borrow occurs here
4 |     text.clear();
  |     ^^^^^^^^^^^^ mutable borrow occurs here
5 |     println!("First word: {word}");
  |                            ---- immutable borrow later used here

7. Safety

Let's run it. Now, what if we clear the text while we still hold the word?

bash
cargo run

8. Error

Rust says no. The word borrows the text, so we can't change the text while the word is still in use. Without this check, word would point at deleted data.

9. String vs &str

Now, the big question. A String owns its text, lives on the heap, and can grow. An ampersand str is a string slice: it only borrows text that lives somewhere else.

rust
fn main() {
    let literal: &str = "I am a string literal";

    let mut owned: String = String::from("I can grow");
    owned.push_str("!");

    greet(literal);
    greet(&owned);
    greet("Ferris");

    let copy: String = literal.to_string();
    println!("{copy}");
}

fn greet(text: &str) {
    println!("Got: {text}");
}

Output: Got: I am a string literal / Got: I can grow! / Got: Ferris / I am a string literal

10. Literals

A string literal in quotes is an ampersand str. Its text is stored inside the program itself.

11. Parameters

For function parameters, prefer ampersand str. greet works with a literal, with a borrowed String, and with any text.

12. to_string

To turn an ampersand str into an owned String, call to string.

13. Run C

Let's run it.

bash
cargo run

14. Array slices

Slices work on arrays too. This takes the middle three numbers. To print it, we use colon question mark, the debug format.

rust
fn main() {
    let numbers = [10, 20, 30, 40, 50];
    let middle = &numbers[1..4];
    println!("{middle:?}");
    println!("Length: {}", middle.len());
}

Output: [20, 30, 40] / Length: 3

15. Run D

Twenty, thirty, forty, and the length is three.

bash
cargo run

Recap

To recap: a slice borrows part of a string or an array. String owns its text and can grow. Ampersand str borrows text. And for parameters, ampersand str works with both.

ยฉ 2026 All Rights Reserved By Mahmudul Alam