Rust Tuples
Sometimes a few values belong together: a name and an age, the two sides of a rectangle, a city and its temperature. A tuple keeps a small, fixed group of values together in one package. The values can even have different types.
You write a tuple with round brackets and commas:
fn main() {
let person = ("Anil", 34, 1.78);
println!("Name: {}", person.0);
println!("Age: {}", person.1);
println!("Height: {} m", person.2);
}Name: Anil Age: 34 Height: 1.78 m
You get each value with a dot and its position, starting from 0. The type of this tuple is (&str, i32, f64): Rust remembers the type of every position.
Unpacking a tuple
Writing .0 and .1 all the time is not very descriptive. You can destructure a tuple, which means unpacking it into separate variables with names in one go:
fn main() {
let point = (3, -2);
let (x, y) = point;
println!("x is {} and y is {}", x, y);
}x is 3 and y is -2
Returning several values
Tuples really shine when a function needs to give back more than one answer. The function returns a tuple, and the caller unpacks it:
fn min_and_max(numbers: &[i32]) -> (i32, i32) {
let mut smallest = numbers[0];
let mut largest = numbers[0];
for &n in numbers {
if n < smallest {
smallest = n;
}
if n > largest {
largest = n;
}
}
(smallest, largest)
}
fn main() {
let temperatures = [21, 25, 19, 30, 27];
let (low, high) = min_and_max(&temperatures);
println!("Coldest {}, warmest {}", low, high);
}Coldest 19, warmest 30
The &n in for &n in numbers unpacks each borrowed number into a plain copy, so we can compare it directly.
Printing a whole tuple
To print a tuple in one go, use {:?} instead of {}. The ? asks for the debug format, a programmer friendly view that most Rust types support:
fn main() {
let rgb = (255, 128, 0);
println!("Orange is {:?}", rgb);
let empty = ();
println!("The empty tuple looks like {:?}", empty);
}Orange is (255, 128, 0) The empty tuple looks like ()
The empty tuple () is called the unit type. It is what a function returns when it returns nothing, such as main. You will see the name in compiler messages, and now you know what it means.
When a group of values needs names for each part, a struct is usually clearer than a tuple. We get there in a few topics.
Practice exercises
- Make a tuple with a city name, its population and whether it is a capital, and print each part.
- Write a function that takes a total in minutes and returns
(hours, minutes). - Swap two numbers using a tuple:
let (a, b) = (b, a);.