What is a slice in Rust and how does it borrow from a collection?
Learn what a Rust slice is, how &[T] and &str borrow from collections as fat pointers, with examples, common mistakes, and interview questions with answers.
Expected Interview Answer
A slice in Rust is a borrowed, dynamically sized view into a contiguous sequence of elements — like `&[T]` or `&str` — that references a portion of an existing array, vector, or string without owning or copying the data.
A slice is a fat pointer holding a start address and a length, so it knows exactly which run of elements it covers. Because it only borrows, the borrow checker guarantees the underlying collection outlives the slice and that no conflicting mutable access happens while an immutable slice is alive. Slices let functions accept `&[T]` instead of a specific `&Vec<T>`, making APIs flexible and zero-copy.
- Zero-copy access to part of a collection
- Works uniformly over arrays, vectors, and strings
- Bounds are known at runtime, preventing overruns
- Encourages flexible APIs that take &[T] or &str
- Borrow checker enforces the source outlives the slice
AI Mentor Explanation
A slice is like a highlights reel that shows overs 10 to 20 of a match without re-recording the footage: it just points at where in the full broadcast tape that span begins and how many deliveries it covers. The original match recording still owns the video; the reel merely borrows a window, so if the tape is erased the reel is meaningless.
Step-by-Step Explanation
Step 1
Start with an owner
Create a Vec, array, or String that actually owns the data on the heap or stack.
Step 2
Take a range
Use range syntax like &v[2..5] to borrow elements from index 2 up to but not including 5.
Step 3
Get a fat pointer
The slice stores a pointer to the first element and a length, so its size is known at runtime.
Step 4
Respect the borrow
While the slice is alive you cannot mutate or drop the source in conflicting ways; the borrow checker enforces this.
Step 5
Pass it around
Write functions that accept &[T] or &str so they work with any compatible collection without copying.
What Interviewer Expects
- Slices are borrowed views, not owning types
- Understanding of the fat pointer (ptr + len) representation
- Difference between &[T], &str, and owned Vec<T>/String
- How lifetimes tie a slice to its source
- Why &[T] parameters make APIs more general
Common Mistakes
- Claiming a slice copies or owns the underlying data
- Forgetting slice ranges are half-open (start inclusive, end exclusive)
- Confusing &str (a slice) with String (an owning type)
- Ignoring that mutable and immutable slices cannot coexist
- Slicing a String by byte index that splits a UTF-8 character
Best Answer (HR Friendly)
“A slice is Rust's way of looking at just part of a list or text without making a copy of it. It simply points at where that portion starts and how long it is, and it stays valid only as long as the original data does.”
Code Example
fn sum(nums: &[i32]) -> i32 {
nums.iter().sum()
}
fn main() {
let v = vec![10, 20, 30, 40, 50];
let middle = &v[1..4]; // borrows 20, 30, 40
println!("sum = {}", sum(middle)); // 90
let s = String::from("hello world");
let word: &str = &s[0..5]; // string slice "hello"
println!("first word = {}", word);
}Follow-up Questions
- What is the difference between &str and String in Rust?
- How is a slice represented in memory as a fat pointer?
- Why can't you index a String by character position directly?
- How do mutable slices (&mut [T]) interact with the borrow checker?
- What does split_at return and how does it borrow?
MCQ Practice
1. What does a Rust slice &[T] store internally?
A slice is a fat pointer consisting of a pointer to the first element and a length, giving a bounded borrowed view.
2. What does the range &v[2..5] include?
Rust ranges are half-open: the start index is inclusive and the end index is exclusive, so 2..5 covers 2, 3, and 4.
3. Which type is a string slice?
&str is a borrowed slice of UTF-8 bytes, while String is the owned, growable string type.
Flash Cards
What is a slice in Rust? — A borrowed, dynamically sized view (&[T] or &str) into a contiguous run of elements in an existing collection.
How is a slice represented? — As a fat pointer: a pointer to the first element plus a length.
Are slice ranges inclusive? — The start is inclusive and the end is exclusive, so a..b covers a up to b-1.
&str vs String? — &str is a borrowed slice of text; String is the owned, heap-allocated, growable string.