C.W.K.
Stream
Lesson 04 of 05 · published

Slices — Borrowing a Piece

~11 min · borrowing, slices, str

Level 0Rust Curious
0 XP0/80 lessons0/19 achievements
0/100 XP to next level100 XP to go0% complete

A slice is a reference to a contiguous piece of a collection — not the whole thing, not a copy, just a borrowed window into part of it.

String slices

&str is a string slice: a borrowed view into string data. &s[0..5] borrows the first five bytes of a String. A string literal like "hello" is itself a &str — a slice pointing into your compiled binary. This is the deeper reason functions should take &str: it accepts both literals and borrowed Strings.

Array and vector slices

The same idea works on any sequence. &v[1..3] borrows a window into a vector — a slice of type &[T]. The slice knows its start and length; it doesn't own the elements, so it can't outlive the collection it points into. The borrow checker guarantees that.

Take &str and &[T], not &String and &Vec. The slice forms are more general: a &str parameter accepts literals, full Strings, and substrings alike. Idiomatic Rust signatures borrow slices, not owned-collection references.

Why slices are safe here and unsafe in C

In C, a pointer-plus-length into an array is a bug waiting to happen — free the array and the pointer dangles. In Rust, a slice borrows the collection, so the borrow checker won't let the collection be dropped or mutated while the slice is alive. Same performance, none of the danger.

Code

Slices borrow a window, not a copy·rust
fn first_word(s: &str) -> &str {
    let bytes = s.as_bytes();
    for (i, &b) in bytes.iter().enumerate() {
        if b == b' ' {
            return &s[0..i]; // a slice into the original string
        }
    }
    s
}

fn main() {
    let phrase = String::from("fearless concurrency");
    let word = first_word(&phrase); // &String coerces to &str
    println!("{word}");             // fearless

    let nums = [10, 20, 30, 40];
    let middle = &nums[1..3];       // a &[i32] slice
    println!("{middle:?}");         // [20, 30]
}

External links

Exercise

Write fn first_word(s: &str) -> &str that returns the first space-delimited word. Call it with a String and with a string literal. Why does the same function work for both without any conversion code on your part?
Hint
A &String auto-coerces to &str, and a literal already is a &str. Taking &str means one signature serves every kind of string input.

Progress

Progress is local-only — sign in to sync across devices.
Spotted a bug or have feedback on this page?Report an Issue
💛 by Ttoriwarm

Comments 0

🔔 Reply notifications (sign in)
Sign inPlease sign in to comment.

No comments yet — be the first.