What Are Arrays in Rust?
An array in Rust is a collection of elements of the same type, stored in contiguous memory locations. Arrays have a fixed size determined at compile time, meaning their length cannot change during runtime.
Arrays are ideal when you know the exact number of elements and require a fast, predictable access pattern.
Key Features of Rust Arrays
- Fixed Size: The length of an array is determined at compile time and cannot be modified.
- Homogeneous Data: All elements in an array must be of the same type.
- Zero-Based Indexing: Array indexing starts from
0
. - Efficient Access: Elements are accessed directly using their index, making arrays highly efficient.
Syntax of Arrays in Rust
Declaring an Array
You can declare an array using square brackets ([ ]) and specifying the type and size.
fn main() {
let numbers: [i32; 5] = [1, 2, 3, 4, 5];
println!("{:?}", numbers);
}
Here:
- [i32; 5]: Specifies an array of type i32 with a fixed size of 5.
Default Values
You can initialize an array with the same value for all elements.
fn main() {
let zeros = [0; 5]; // Creates an array [0, 0, 0, 0, 0]
println!("{:?}", zeros);
}
Accessing Array Elements
You can access array elements using their index, enclosed in square brackets ([ ]).
fn main() {
let fruits = ["Apple", "Banana", "Cherry"];
println!("First fruit: {}", fruits[0]);
println!("Second fruit: {}", fruits[1]);
}
- Note: If you try to access an index that is out of bounds, Rust will throw a runtime error, ensuring safety.
Iterating Over Arrays
Rust provides multiple ways to iterate through arrays:
Using a for Loop
fn main() {
let numbers = [10, 20, 30, 40, 50];
for num in numbers {
println!("{}", num);
}
}
Using the .iter() Method
fn main() {
let numbers = [10, 20, 30, 40, 50];
for num in numbers.iter() {
println!("{}", num);
}
}
Array Operations
Length of an Array
You can determine the size of an array using the .len() method.
fn main() {
let numbers = [1, 2, 3, 4, 5];
println!("Length of the array: {}", numbers.len());
}
Slicing an Array
Slices provide a view into a contiguous sequence of elements in an array without copying them.
fn main() {
let numbers = [1, 2, 3, 4, 5];
let slice = &numbers[1..4]; // Includes elements at index 1, 2, and 3
println!("{:?}", slice);
}
Modifying Arrays
You can only modify arrays if they are declared as mutable.
fn main() {
let mut numbers = [1, 2, 3];
numbers[1] = 20; // Changing the second element
println!("{:?}", numbers);
}
Multidimensional Arrays
Rust supports multidimensional arrays, where each element of an array is another array.
fn main() {
let matrix: [[i32; 3]; 2] = [
[1, 2, 3],
[4, 5, 6],
];
println!("{:?}", matrix);
println!("Element at [0][1]: {}", matrix[0][1]);
}
Here:
- [[i32; 3]; 2]: Represents a 2×3 matrix (2 rows, 3 columns).
Array Limitations in Rust
- Arrays are fixed in size, making them less flexible for dynamic scenarios. Use vectors (Vec<T>) when you need a resizable collection.
- Arrays require all elements to be of the same type. For mixed-type collections, use tuples or enums.
Practical Example: Calculating the Average
fn main() {
let numbers = [10, 20, 30, 40, 50];
let sum: i32 = numbers.iter().sum();
let average = sum as f32 / numbers.len() as f32;
println!("Average: {}", average);
}
Best Practices with Rust Arrays
- Use arrays for fixed-size collections to leverage compile-time safety and performance.
- Avoid accessing elements out of bounds to prevent runtime errors.
- Use slices for flexible, read-only views of array elements.
Key Differences: Arrays vs. Vectors
Feature | Arrays | Vectors |
---|---|---|
Size | Fixed | Dynamic |
Initialization | Compile-time | Runtime |
Flexibility | Less flexible | Highly flexible |