#7 Slices
&str, &[T], string slices
What is a slice?
A slice is a reference to a contiguous sequence of elements within a collection. Slices let you reference a portion of data without copying it and without taking ownership.
Slices are one of the most common types in Rust. They are written as &[T] for arrays and &str for strings.
String slices (&str)
A string slice (&str) is a reference to a part of a String. You create one using range syntax:
let s = String::from("Hello, world!");
let hello = &s[0..5]; // "Hello"
let world = &s[7..12]; // "world"
// Shorthand: omit start or end
let hello = &s[..5]; // Same as &s[0..5]
let world = &s[7..]; // Same as &s[7..13]
let full = &s[..]; // The whole string
println!("First word: {hello}");String literals like "hello" are already &str — they are slices pointing to a specific point in the binary. That is why the type of a string literal is &str, not String.
fn first_word(s: &str) -> &str {
let bytes = s.as_bytes();
for (i, &byte) in bytes.iter().enumerate() {
if byte == b' ' {
return &s[..i];
}
}
s // No space found — return the whole string
}
let sentence = String::from("Hello world");
let word = first_word(&sentence);
println!("First word: {word}"); // "Hello"Array slices (&[T])
Array slices work the same way. They reference a portion of an array or vector:
let numbers = [1, 2, 3, 4, 5];
let slice = &numbers[1..4]; // [2, 3, 4]
println!("Slice: {:?}", slice);
let first_two = &numbers[..2]; // [1, 2]
let last_two = &numbers[3..]; // [4, 5]
let all = &numbers[..]; // [1, 2, 3, 4, 5]The type &[i32] is a slice of i32 values. It stores a pointer to the first element and a length.
Slices as function parameters
Using slices as function parameters makes your functions more flexible. A function that takes &str can accept both String and &str values:
fn sum(numbers: &[i32]) -> i32 {
let mut total = 0;
for &n in numbers {
total += n;
}
total
}
fn greet(name: &str) -> String {
format!("Hello, {name}!")
}
fn main() {
let nums = vec![1, 2, 3, 4, 5];
println!("Sum: {}", sum(&nums));
// Works with arrays too
let arr = [10, 20, 30];
println!("Sum: {}", sum(&arr));
// &str works with both String and &str
let name = String::from("world");
println!("Greeting: {}", greet(&name));
println!("Greeting: {}", greet("Rust"));
}Tip: prefer &str over &String and &[T] over &Vec<T> in function signatures. This makes your functions more generic and idiomatic.
Your turn
Try running the slices demo with cargo run and cargo check in the terminal below: