Slices
let slice = &array[start..end];
let slice = &vec[..end];
let slice = &vec[start..];
fn name(param: &[Type]) {}
Slicing an Array
A slice references a contiguous portion of a collection using range syntax inside square brackets, without copying the underlying elements.
Example: Slicing an Array
// Entry point: execution of the program starts here
fn main() {
// Declare an immutable variable `numbers`, set to `[10, 20, 30, 40, 50]`
let numbers = [10, 20, 30, 40, 50];
// Declare an immutable variable `middle`, set to `&numbers[1..4]`
let middle = &numbers[1..4];
// Print "{:?}" to the console, substituting in `middle` (with a trailing newline)
println!("{:?}", middle);
}
Login to try C/C++/Java/PHP code in the editor
Slicing a Vector
Slices work the same way on a Vec, letting you view a portion of it as &[T] while the Vec itself keeps ownership of the data.
Example: Slicing a Vector
// Entry point: execution of the program starts here
fn main() {
// Declare an immutable variable `scores`, set to `vec![90, 85, 77, 92]`
let scores = vec![90, 85, 77, 92];
// Declare an immutable variable `top_two`, set to `&scores[0..2]`
let top_two = &scores[0..2];
// Print "Top two: {:?}" to the console, substituting in `top_two` (with a trailing newline)
println!("Top two: {:?}", top_two);
}
Login to try C/C++/Java/PHP code in the editor
Full Slices
Omitting both ends of a range, &collection[..], produces a slice covering the entire collection, which is useful when a function parameter expects a slice type rather than an owned collection.
Example: Full Slices
// Define the function `total` taking `values` and returning an integer
fn total(values: &[i32]) -> i32 {
values.iter().sum()
}
// Entry point: execution of the program starts here
fn main() {
// Declare an immutable variable `data`, set to `vec![1, 2, 3, 4]`
let data = vec![1, 2, 3, 4];
// Print "Sum: {}" to the console, substituting in `total(&data[..])` (with a trailing newline)
println!("Sum: {}", total(&data[..]));
}
Login to try C/C++/Java/PHP code in the editor
Slices Borrow Their Source
Because a slice is a reference, it follows the same borrowing rules: the original collection cannot be mutated while an active slice of it still exists.
Example: Slices Borrow Their Source
// Entry point: execution of the program starts here
fn main() {
// Declare an immutable variable `letters`, set to `['a', 'b', 'c', 'd']`
let letters = ['a', 'b', 'c', 'd'];
// Declare an immutable variable `part`, set to `&letters[1..3]`
let part = &letters[1..3];
// Print "Slice: {:?}" to the console, substituting in `part` (with a trailing newline)
println!("Slice: {:?}", part);
// Print "Original still usable: {:?}" to the console, substituting in `letters` (with a trailing newline)
println!("Original still usable: {:?}", letters);
}
Login to try C/C++/Java/PHP code in the editor
- Trying to slice out of bounds, e.g.
&array[0..10]on a 5-element array, which panics at runtime. - Forgetting slices borrow from the original data, so the original collection cannot be mutated while a slice of it is in use.
- Confusing
&vec[..](a slice of the whole vector) withvecitself (an owned value) when passing data to functions.
- A slice, written
&[T]or&str, references a contiguous sequence of elements without owning them. - Range syntax like
1..3selects a sub-range of a collection to slice. - Slices borrow from their source, so borrowing rules still apply to them.
- Slices let functions accept both full collections and partial views with one flexible parameter type.
Chapter Quiz — Complete all 6 topics to unlock
0/6 topics done
Complete these topics first: