In this lesson, you will learn how to use slices to inspect parts of a collection without taking ownership or copying the underlying data.
The Concept of a "View"
Imagine you have a long document (like a Vec or an array) and you want to hand someone a specific paragraph. You don’t want to hand them the entire document, nor do you want to print a duplicate copy. Instead, you point them to a specific section of your document. In Rust, we call this a slice.
A slice is a reference to a contiguous sequence of elements. Because it is a reference, it does not own the data—it merely acts as a "view" into a portion of another collection.
How to Create a Slice
You create a slice by using a range syntax [start..end] on an array or a vector. Here is a simple example:
fn main() {
let numbers = [10, 20, 30, 40, 50];
// Create a slice that "views" the second and third elements
let slice = &numbers[1..3];
println!("The slice contains: {:?}", slice);
}
In the code above, &numbers[1..3] creates a slice that starts at index 1 and goes up to, but does not include, index 3. The slice contains [20, 30].
Why Use Slices?
- Efficiency: Because a slice is just a view (storing a pointer to the start and a length), it never copies the data. Whether your original vector has 10 elements or 10 million, creating a slice is nearly instantaneous.
- Safety: When you create a slice, the borrow checker ensures that your view remains valid. If you try to modify the original collection in a way that would invalidate the memory the slice is pointing to, the compiler will stop you.
- Flexibility: Slices are the standard way to pass "a portion of a list" into functions, making your code highly reusable.
By using slices, you can write clean, high-performance code that interacts with parts of your data without the overhead of moving or duplicating memory.
Key Takeaway: Slices act as non-owning, efficient "windows" into contiguous data, allowing you to access segments of a collection without copying them.