Step 1 of 6
Tuples: several values in one
So far every variable has held one value: one number, one bool, one char. Real data comes in groups. A point has an x and a y; an order has a number, a quantity and a price. Rust has two built-in compound types for grouping values, tuples and arrays, and this module covers both. At the end you'll get a first look at Vec, a list that can grow.
Making a tuple
A tuple groups a fixed number of values, and the values can have different types. Write them in parentheses, separated by commas:
fn main() {
let order = (1042, 3, 19.99);
println!("order {} has {} items at {} each", order.0, order.1, order.2);
println!("{:?}", order);
}
order 1042 has 3 items at 19.99 each
(1042, 3, 19.99)
Piece by piece:
orderholds three values at once. Its type is written like the value, with types in place of values:(i32, i32, f64). Rust infers it, but you can write it yourself:let order: (i32, i32, f64) = (1042, 3, 19.99);order.0,order.1andorder.2read the parts. Positions start at 0, as almost everywhere in programming. The number after the dot is part of your code: you can't put a variable there (order.idoesn't work).{}can't print a whole tuple, but{:?}, the debug format you met with variables, can.
Changing a part
A tuple's length and the types of its parts never change, but with let mut you can change the values:
fn main() {
let mut score = (0, 0); // (home, away)
score.0 += 2;
score.1 += 1;
println!("Home {} - {} Away", score.0, score.1);
}
Home 2 - 1 Away
A comment like // (home, away) is worth writing, because .0 and .1 don't say what they mean. When a group of values deserves real names, you'll use a struct (module 12). Tuples are best for small groups that don't live long, like a function returning two results (next step).
Common mistakes
- Asking for a part that doesn't exist. A three-value tuple has
.0,.1and.2. The compiler catches.3:
fn main() {
let order = (1042, 3, 19.99);
println!("{}", order.3);
}
error[E0609]: no field `3` on type `({integer}, {integer}, {float})`
{integer} and {float} mean "some integer (or float) type, not pinned down yet". The note below the error lists the fields that do exist: `0`, `1`, `2`.
- Printing a tuple with
{}. Error E0277 says the tuple "doesn't implementstd::fmt::Display", and a note suggests{:?}.{}is for values with one obvious human-readable form, like a number. A tuple only has the debug form. - A one-value tuple needs a trailing comma:
(5,)is a tuple, while(5)is just the number 5 in parentheses. You'll rarely need one.
Your task
Fill in the blanks so the program prints the player's name and level from the tuple, then the whole tuple in the debug format:
Ferris is level 7
("Ferris", 7, true)
Challenge 2
A shop tracks (product, count) in a tuple. Five apples were just sold. Fill the blanks: make the tuple changeable, and subtract from the right part so the program prints apples left: 7.
Challenge 3
The tuple rect holds a rectangle's width and height. Print its area and perimeter, computing both from rect.0 and rect.1 (don't type the answers):
area: 40
perimeter: 26