Rust The Slice Type
A slice is a reference to a part of a collection. Instead of copying data, a slice points to a section of an existing array or string. Slices let you work with portions of data efficiently without needing to own the entire thing.
String Slices
A string slice is a reference to part of a String. The type is written as &str.
let sentence = String::from("hello world");
let hello = &sentence[0..5]; ← Slice: characters 0 to 4
let world = &sentence[6..11]; ← Slice: characters 6 to 10
println!("{} {}", hello, world);
Output:
hello world
Range Syntax
The range [start..end] includes the character at start and stops before end. You can shorten the range when starting from zero or going to the end:
let s = String::from("hello");
let slice1 = &s[0..3]; ← "hel"
let slice2 = &s[..3]; ← Same thing: start from beginning
let slice3 = &s[2..5]; ← "llo"
let slice4 = &s[2..]; ← From index 2 to end: "llo"
let slice5 = &s[..]; ← Entire string
The Ruler Diagram
sentence: h e l l o w o r l d index: 0 1 2 3 4 5 6 7 8 9 10 &sentence[0..5] → h e l l o (indices 0,1,2,3,4) &sentence[6..11] → w o r l d (indices 6,7,8,9,10)
Why Slices Are Useful
Consider a function that finds the first word in a sentence. Without slices, you might return the index where the word ends — but that index becomes meaningless if the original string changes later. A slice solves this because it holds a direct reference to the actual characters.
fn first_word(s: &String) -> &str {
let bytes = s.as_bytes();
for (i, &item) in bytes.iter().enumerate() {
if item == b' ' { ← Found a space
return &s[0..i]; ← Return slice up to the space
}
}
&s[..] ← No space found: return the whole string
}
fn main() {
let sentence = String::from("hello world");
let word = first_word(&sentence);
println!("First word: {}", word);
}
Output:
First word: hello
How the Slice Stays Valid
The slice borrows part of sentence. Rust's borrow checker ensures sentence cannot be modified or dropped while the slice is still in use. This prevents bugs where a reference points to changed or freed data.
String Literals Are Slices
When you write a string literal in your code, it is stored directly in the program binary. Its type is &str — an immutable string slice pointing into the binary. This is why string literals are always valid for the life of the program.
let greeting = "Hello, world!"; // ↑ // Type: &str — a slice pointing to text in the binary
String vs &str
String ← Owned, heap-allocated, can grow and shrink &String ← Reference to a whole String &str ← Slice: reference to part (or all) of any string data
Functions that only need to read a string should accept &str instead of &String. A &str works with both String values and string literals, making functions more flexible.
Array Slices
Slices work on arrays too, not just strings. The type is written as &[T] where T is the element type:
fn sum(numbers: &[i32]) -> i32 {
let mut total = 0;
for n in numbers {
total += n;
}
total
}
fn main() {
let all = [10, 20, 30, 40, 50];
let total_all = sum(&all); ← Pass the whole array
let total_part = sum(&all[1..4]); ← Pass elements 1, 2, 3
println!("Total: {}", total_all); ← 150
println!("Part: {}", total_part); ← 90
}
The Window Diagram
all: [ 10 | 20 | 30 | 40 | 50 ]
↑ ↑
&all[1..4] is a window showing [ 20 | 30 | 40 ]
The data is not copied — the slice just points into it.
Key Properties of Slices
Property Detail --------- ------ Ownership None — slices borrow from an owner Mutability Can be &[T] (read only) or &mut [T] (read-write) Length Tracked automatically inside the slice Bounds checking Accessing out-of-bounds panics at runtime
Bounds Checking
If you try to access a slice index that does not exist, Rust panics with a clear message instead of silently reading bad memory:
let numbers = [1, 2, 3]; let bad = &numbers[1..10]; ← Panic: index out of bounds
This is safer than C, where an out-of-bounds access reads random memory without any warning.
Quick Reference
&s[..] ← Slice of entire string s &s[0..5] ← Slice of first 5 characters &s[3..] ← Slice from index 3 to end &arr[1..4] ← Slice of array elements 1, 2, 3 &str ← String slice type &[i32] ← Integer array slice type
