Tuples & Arrays
Prerequisites: Strings: String vs &str
Tuples and arrays are Rust's two built-in compound types. Both have a fixed length that never changes.
Syntax
let person: (&str, i32, bool) = ("Ada", 36, true); // tuple
let name = person.0; // access by position
let (n, age, active) = person; // destructuring
let scores: [i32; 3] = [90, 85, 77]; // array: [type; length]
let zeros = [0; 5]; // [0, 0, 0, 0, 0]
let first = scores[0]; // access by index
Tuples group a fixed number of values that can have different
types. Access fields with .0, .1, and so on, or unpack them all
at once with a let (a, b, c) = ... pattern. Tuples are an easy way
to return several values from a function. The empty tuple () is
called the unit type — it's what functions without a return value
return.
Arrays hold a fixed number of values of the same type. The
length is part of the type: [i32; 3] and [i32; 4] are different
types. Arrays live on the stack. When you need a list that can grow,
use a vector (next lesson).
Indexing is checked: an out-of-range index stops the program with a panic instead of reading random memory.
Example
fn min_max(values: [i32; 5]) -> (i32, i32) {
let mut min = values[0];
let mut max = values[0];
for v in values {
if v < min {
min = v;
}
if v > max {
max = v;
}
}
(min, max)
}
fn main() {
let person = ("Ada", 36, true);
println!("{} is {}", person.0, person.1);
let (name, age, active) = person;
println!("{name}, {age}, active: {active}");
let point = (3, -2);
let (x, y) = point;
println!("x = {x}, y = {y}");
let scores = [90, 85, 77, 62, 98];
println!("first: {}, last: {}", scores[0], scores[scores.len() - 1]);
println!("{} scores: {scores:?}", scores.len());
let (low, high) = min_max(scores);
println!("low: {low}, high: {high}");
let mut grid = [[0; 3]; 2];
grid[1][2] = 7;
println!("{grid:?}");
}
Expected output
Ada is 36
Ada, 36, active: true
x = 3, y = -2
first: 90, last: 98
5 scores: [90, 85, 77, 62, 98]
low: 62, high: 98
[[0, 0, 0], [0, 0, 7]]
Common mistakes
- Indexing past the end with a constant index. The compiler catches it:
let numbers = [1, 2, 3];
println!("{}", numbers[5]);
error: this operation will panic at runtime
followed by index out of bounds: the length is 3 but the index is 5.
If the index is only known at runtime, the program compiles and
panics when it runs instead.
- Trying to
pushonto an array. Arrays can't grow; use aVec. - Mixing types in an array, like
[1, "two"]. Every element must have the same type — use a tuple if you need mixed types.
Practice
Write a function stats(values: [f64; 4]) -> (f64, f64) that returns
the sum and the average of four numbers. Call it with
[2.0, 4.0, 6.0, 8.0] and print Sum: 20, average: 5.
Show solution
fn stats(values: [f64; 4]) -> (f64, f64) {
let mut sum = 0.0;
for v in values {
sum += v;
}
(sum, sum / values.len() as f64)
}
fn main() {
let (sum, average) = stats([2.0, 4.0, 6.0, 8.0]);
println!("Sum: {sum}, average: {average}");
}