Step 7 of 7
Nested loops and labels
A loop inside another loop is a nested loop: the inner loop runs completely for every single iteration of the outer one. That's how you walk over grids and tables:
fn main() {
for row in 1..=3 {
for col in 1..=4 {
print!("{} ", row * col);
}
println!();
}
}
1 2 3 4
2 4 6 8
3 6 9 12
The inner body runs 3 × 4 = 12 times in total. The println!() belongs to the outer loop, so it ends each row.
Breaking out of an outer loop
break and continue apply to the innermost loop. To target an outer one, give it a label: a name starting with an apostrophe, like 'search:, written before the loop. Then break 'search; leaves that loop, and continue 'search; jumps to its next iteration:
fn main() {
let target = 42;
'search: for a in 1..=10 {
for b in a..=10 {
if a * b == target {
println!("found {a} x {b} = {target}");
break 'search;
}
}
}
println!("search finished");
}
found 6 x 7 = 42
search finished
Without the label, break would only leave the inner loop, and the outer loop would carry on searching with a = 7, 8, ..., wasting work (and possibly printing more matches).
continue 'outer means "give up on the rest of this row and start the next one". Labels work on loop and while too, and a labeled loop can even break 'label value.
Common mistakes
- Forgetting the label on
break, so only the inner loop stops. - Label syntax: the label is declared as
'search:in front of the loop and used asbreak 'search;, both with the apostrophe. Labels look like lifetimes (a later topic) but have nothing to do with them. - Deep nesting: three or four levels of loops are hard to read. At work, a nested search usually becomes its own function that
returns the answer as soon as it finds it.
Your task
Print a right triangle of * with 5 rows, where row 1 has one star and row 5 has five. Use two nested for loops: print!("*") in the inner loop, and println!() after it to end each row.
*
**
***
****
*****
Challenge 2
Find the pair of whole numbers a and b (with 1 <= a <= b <= 20) whose sum is 23 and whose product is 120. Search with nested loops (a from 1 to 20, b from a to 20), and count every pair you check in a variable checked. When you find the pair, print it and stop both loops with a labeled break. After the loops, print the count:
found a=8 b=15
checked 127 pairs
(With a plain break, the outer loop would keep going and the count would be wrong.)
Challenge 3
Write fn count_pairs(limit: u32, target: u32) -> u32 that counts the pairs of numbers a and b with 1 <= a < b <= limit and a + b == target. For example, count_pairs(5, 6) is 2: the pairs (1, 5) and (2, 4). Use nested for loops.