Skip to content

Rust Slices

A slice lets you borrow a section of an array or vector — a “view” into part of it — without copying the data or taking ownership. If you’ve used borrowing with a single value, a slice is the same idea applied to a range of elements.

fn main() {
let numbers = [10, 20, 30, 40, 50];
let middle = &numbers[1..4]; // elements at index 1, 2, 3
println!("{:?}", middle);
}

Output:

[20, 30, 40]
▶ Try it Yourself

1..4 is the same kind of range you saw in for loops — it starts at index 1 and stops before index 4, so you get indices 1, 2, and 3.

A few shortcuts that come up often:

fn main() {
let numbers = [10, 20, 30, 40, 50];
println!("{:?}", &numbers[..3]); // from the start up to index 3 -> [10, 20, 30]
println!("{:?}", &numbers[2..]); // from index 2 to the end -> [30, 40, 50]
println!("{:?}", &numbers[..]); // the whole thing -> [10, 20, 30, 40, 50]
}
▶ Try it Yourself

You’ve actually already been using slices — &str is a slice of a String (or of another string)! This is why the two types work so well together:

fn main() {
let sentence = String::from("The quick brown fox");
let first_word = &sentence[0..3];
println!("{first_word}"); // "The"
}
▶ Try it Yourself

You could imagine solving this by copying out a new Vec or String for the section you want. Slices avoid that entirely — they just point at part of the existing data, the same way a reference (&) points at a single value. That means no extra allocation, no copying, and the borrowing rules you already know from the Borrowing page still apply.

Slices are especially useful as function parameters, because they accept both arrays and vectors:

fn sum(numbers: &[i32]) -> i32 {
let mut total = 0;
for n in numbers {
total += n;
}
total
}
fn main() {
let array = [1, 2, 3];
let vector = vec![4, 5, 6];
println!("{}", sum(&array));
println!("{}", sum(&vector));
}
▶ Try it Yourself

&[i32] accepts a slice from either an array or a Vec — one function, both call sites work.

  • A slice (&[T]) borrows a section of an array or vector without copying it.
  • 1..4 selects indices 1 through 3; leave off either side of .. to go from the start or to the end.
  • &str is itself a slice of text — that’s why strings and slices share so much behavior.
  • Prefer &[T] as a function parameter type when you want to accept both arrays and vectors.

Quick check

1. What does a slice let you do with part of an array or vector?

2. Which indices does &numbers[1..4] include?

3. Why is &[i32] a good choice for a function parameter type?

Score: 0 / 3