In Rust, an array is a fixed-size collection of values of the same type. A slice is a view into a portion of an array. Arrays are useful when you know the number of elements at compile time, and slices let you work with a section of an array without copying data.
When you need to store multiple values of the same type in Rust, the two main tools are arrays and slices. If you are coming from JavaScript, think of arrays as similar to JS arrays but with a fixed size, and slices as read-only views into a list.
In this post, I will explain how arrays and slices work in Rust, how to use them in your programs, and why Rust separates these two concepts.
Defining Arrays
An array in Rust is defined using square brackets:
let numbers = [1, 2, 3, 4, 5];
All elements must be of the same type. Rust infers the type and length from the literal, or you can be explicit:
let numbers: [i32; 5] = [1, 2, 3, 4, 5];
This defines an array of 5 elements, all of type i32.
Fixed Length
Rust arrays have a fixed size known at compile time. You cannot add or remove elements like you would in a dynamic list. For resizable collections, you will use Vec later on.
You can also create arrays with repeated values:
let zeros = [0; 5]; // same as [0, 0, 0, 0, 0]
Accessing Elements
Access items using their index:
let first = numbers[0];
let last = numbers[4];
Rust will panic at runtime if you access an index out of bounds:
let x = numbers[5]; // will crash the program
Iterating Over Arrays
You can use a loop to process each item:
for num in numbers {
println!("{}", num);
}
This works because arrays implement the IntoIterator trait.
Array Length
You can get the number of elements with .len():
println!("Length: {}", numbers.len());
Introducing Slices
A slice is a reference to a part of an array. You do not own the data, just a window into it:
let slice = &numbers[1..4]; // elements at index 1, 2, 3
This gives you a slice of type &[i32]. Slices are very useful for writing functions that take flexible input sizes.
You can also slice the full array:
let all = &numbers[..]; // same as &numbers[0..numbers.len()]
Slices in Functions
Here is a function that takes a slice:
fn print_slice(slice: &[i32]) {
for val in slice {
println!("{}", val);
}
}
And you can call it with:
print_slice(&numbers[0..3]);
This is efficient because no data is copied, just a reference is passed.
Example Program
fn main() {
let values = [10, 20, 30, 40, 50];
let slice = &values[1..4];
println!("Array length: {}", values.len());
println!("Second to fourth values:");
for v in slice {
println!("{}", v);
}
}
This program shows how to declare an array, create a slice, and access its values.
Arrays vs. Slices
Feature | Array | Slice |
---|---|---|
Ownership | Owns data | Reference to data |
Size | Fixed at compile time | Dynamically sized |
Type | [T; N] | &[T] |
Mutability | Based on array itself | Based on borrowed data |
Summary
Arrays in Rust are collections of a fixed number of values of the same type. Slices allow you to borrow and work with a subset of an array without copying it. Arrays are fast and memory-safe, and slices give you flexibility when writing functions or processing parts of data.