Thuta Learning
Rust
IntermediateProgrammingbeginner

Slices and Strings — `&str` vs `String`

What you'll walk away with

  • Explain the core ideas behind Slices and Strings — `&str` vs `String`
  • Run the sample Rust code and verify its output
  • Apply the technique correctly to the Tutorial Platform and production scenarios

Build the mental model

A slice is a reference type that points to a contiguous portion of a collection (a string, an array) without taking ownership of it — an array slice `&[1, 2, 3]` gives you a "view" of the whole array or part of it and never owns any data itself. A string slice (`&str`) is a special case of this concept: a borrowed view into a `String`'s owned, growable, heap-allocated data — and string literals (`"hello"`) are also of type `&str`, embedded as compile-time constants directly in the binary. `String` is owned, mutable, and heap-allocated, growing at runtime and modifiable with things like `push_str` or `+`, while `&str` is a borrowed view and therefore immutable. Writing a function parameter's type as `&str` lets it accept both a `String` (via `&my_string`) and a `&str` literal, making it more flexible — a direct, practical example of Lesson 7's "borrow-first design." The key safety guarantee is that the borrow checker prevents the underlying data from being mutated while a slice into it is held, protecting against the classic C-style "dangling slice/pointer" bug entirely at compile time.

Connect it to a real scenario

Write the content analyzer's functions as `fn first_paragraph(text: &str) -> &str` — both the input parameter (`&str`) and return value (`&str`) work with either a `String` (via `&lesson_body`) or a string literal. To extract a lesson body's first 100 characters as preview text, use slice syntax `&text[..100]` — while that slice is held, the underlying `String` cannot be mutated, a direct hands-on example of the borrow checker at work. Store tags as `Vec<String>`, but write functions that filter or search tags with a `&[String]` (slice) parameter, so the caller never needs to move the whole `Vec`.

Try the working example

rust
fn first_paragraph(text: &str) -> &str {
    match text.find("\n\n") {
        Some(pos) => &text[..pos],
        None => text,
    }
}

fn main() {
    let owned = String::from("Ownership basics.\n\nRust prevents data races.");
    println!("{}", first_paragraph(&owned));
    println!("{}", first_paragraph("A literal works too.\n\nSecond part."));
}
You should see
You print "Ownership basics." and "A literal works too.", proving the one function accepts both a String reference and a literal.

5-minute try-it

Write `fn last_word(text: &str) -> &str` that returns the text's last word as a slice (split on whitespace) — test it with both a `String` variable and a string literal.

One important caution

Writing a function's parameter type as `&String` specifically — a string literal cannot be passed directly, giving up the flexibility that `&str` would provide.

Slicing a string by byte index (`&text[..5]`) without checking character boundaries — cutting through the middle of a multi-byte UTF-8 character (like accented or non-Latin text) causes a runtime panic.

The Rust Programming Language — The Slice TypeRust

Easy traps

  • Writing a function's parameter type as `&String` specifically — a string literal cannot be passed directly, giving up the flexibility that `&str` would provide.
  • Slicing a string by byte index (`&text[..5]`) without checking character boundaries — cutting through the middle of a multi-byte UTF-8 character (like accented or non-Latin text) causes a runtime panic.
  • Validate sample code in a local or test environment before applying it to a production system.

Exercise

Write `fn last_word(text: &str) -> &str` that returns the text's last word as a slice (split on whitespace) — test it with both a `String` variable and a string literal.

You'll know it worked when: You print "Ownership basics." and "A literal works too.", proving the one function accepts both a String reference and a literal.

Slices and Strings — `&str` vs `String` | Thuta Learning