RustArena

Step 2 of 6

Destructuring, and returning several values

Writing .0 and .1 everywhere gets tiring, and it hides what the values mean. Destructuring unpacks a tuple into separate, well-named variables in one let:

fn main() {
    let point = (3, -7);
    let (x, y) = point;
    println!("x = {x}, y = {y}");
}
x = 3, y = -7

The left side, (x, y), is a pattern: it has the same shape as the value, and each name receives the part in its position. If you don't need a part, put _ in its place: let (x, _) = point; takes only the x.

Returning several values from a function

A function returns exactly one value, but that value can be a tuple. This is the everyday use of tuples: a function that works out two or three related results at once.

fn sum_and_average(a: f64, b: f64, c: f64) -> (f64, f64) {
    let sum = a + b + c;
    (sum, sum / 3.0)
}

fn main() {
    let (total, avg) = sum_and_average(4.0, 7.5, 9.5);
    println!("total {total:.1}, average {avg:.2}");
}
total 21.0, average 7.00

Two more things tuples explain:

Common mistakes

fn main() {
    let (x, y) = (1, 2, 3);
    println!("{x} {y}");
}
error[E0308]: mismatched types

The full message says expected a tuple with 3 elements, found one with 2 elements. Use _ for a value you want to skip: let (x, y, _) = (1, 2, 3);

Your task

Write div_rem(a, b), which returns the quotient (how many times b fits into a) and the remainder as a tuple. For example div_rem(17, 5) returns (3, 2) because 17 = 3 × 5 + 2. Integer / and % do the work.

Challenge 2

Write split_time(total_seconds), which returns (hours, minutes, seconds). For example split_time(3725) returns (1, 2, 5): one hour, two minutes and five seconds.

Challenge 3

Two weather stations report (name, temperature, online). Destructure each tuple into three named variables with let (...) = ...; and print one line per station:

north: 21.5 C (online)
south: 18 C (offline)

(A float like 18.0 prints as 18 with {}.)

Previous: Tuples: several values in one Next: Arrays: a fixed row of values