Rust For
for loops through a range or a collection, one item at a time. Of the three loop types in Rust, this is the one you’ll reach for the most.
Looping over a range
Section titled “Looping over a range”fn main() { for i in 1..=5 { println!("{i}"); }}Output:
123451..=5 is a range that includes both ends (1 through 5). If you drop the = — 1..5 — it stops one short, giving you 1 through 4. That off-by-one is easy to trip over, so it’s worth double-checking which one you meant.
Looping over a collection
Section titled “Looping over a collection”This is where for really shines — looping over an array or vector without tracking an index yourself:
fn main() { let fruits = ["apple", "banana", "cherry"];
for fruit in fruits { println!("{fruit}"); }}Output:
applebananacherryCompare this to manually counting with a while loop and indexing (fruits[i]) — it’s shorter, and there’s no index to get wrong. You’ll learn more about arrays and vectors on the Arrays and Vectors pages.
Getting the index too, with .enumerate()
Section titled “Getting the index too, with .enumerate()”If you need both the position and the value, use .enumerate():
fn main() { let fruits = ["apple", "banana", "cherry"];
for (index, fruit) in fruits.iter().enumerate() { println!("{index}: {fruit}"); }}Output:
0: apple1: banana2: cherryThe (index, fruit) part is a tuple pattern: each round gives you a pair, and the loop splits it into two variables for you.
Counting backwards and in steps
Section titled “Counting backwards and in steps”What if you want to count down from 3, or only visit every second number? A natural first try is a range that goes backwards, like 3..=1. It compiles, but the loop never runs. A range only counts up, so a range whose start is bigger than its end is simply empty.
Instead, take a normal range and change how you walk through it:
.rev()goes through the range in reverse..step_by(n)takes everynth value, starting with the first.
fn main() { for i in (1..=3).rev() { println!("{i}..."); } println!("Go!");
for even in (0..=10).step_by(2) { print!("{even} "); } println!();
for i in 3..=1 { println!("this never prints: {i}"); }}Output:
3...2...1...Go!0 2 4 6 8 10Notice the parentheses: (1..=3).rev(). Without them, Rust would read 1..=3.rev() as “1 up to 3.rev()”, which isn’t what you want. You can combine the two as well: (0..=10).rev().step_by(5) gives 10, 5, 0.
Why for is preferred over while for counting
Section titled “Why for is preferred over while for counting”You could write a counting loop with while, but for with a range removes an entire category of mistakes — no manual counter to forget to update, and no risk of running one step past the end of an array. Rust programmers reach for for by default and only use while when there isn’t a natural range or collection to loop over.
Practice
Section titled “Practice”1. A times table
Section titled “1. A times table”Print the 7 times table from 7 x 1 = 7 up to 7 x 10 = 70. Hint: one for loop over 1..=10 is enough. You can do the multiplication right inside println!.
Show solution
fn main() { for i in 1..=10 { println!("7 x {i} = {}", 7 * i); }}Output:
7 x 1 = 77 x 2 = 147 x 3 = 217 x 4 = 287 x 5 = 357 x 6 = 427 x 7 = 497 x 8 = 567 x 9 = 637 x 10 = 70Named variables like {i} can go straight inside the braces. A calculation like 7 * i can’t, so it uses an empty {} with the value after the comma.
2. Add up the odd numbers
Section titled “2. Add up the odd numbers”Add up all the odd numbers from 1 to 99 and print the total. Hint: (1..100).step_by(2) gives you 1, 3, 5, … 99. Keep a mut total outside the loop.
Show solution
fn main() { let mut total = 0;
for n in (1..100).step_by(2) { total += n; }
println!("The odd numbers from 1 to 99 add up to {total}");}Output:
The odd numbers from 1 to 99 add up to 2500Another way is to loop over 1..100 and only add n when n % 2 == 1. Both work. step_by just skips the even numbers instead of checking each one.
for item in range_or_collection { ... }is the everyday loop in Rust.1..=5includes both ends;1..5stops one short of 5.- Loop directly over arrays/vectors to get each value without manual indexing.
- Use
.enumerate()when you need the index alongside the value. - A backwards range like
3..=1is empty. Use(1..=3).rev()to count down, and.step_by(n)to skip ahead.
Quick check
Section titled “Quick check”Quick check
1. What's the difference between 1..=5 and 1..5 in a for loop?
2. How do you get both the index and the value while looping over a collection?
3. Why is for generally preferred over while for counting through a collection?
4. What does for i in 5..=1 { ... } do?
Score: 0 / 4
Read more
Section titled “Read more”- Looping Through a Collection with for — The Rust Book: the official introduction, including a countdown with
.rev(). - for and range — Rust by Example: runnable examples of ranges, plus
iter,iter_mutandinto_iterfor collections. - Iterator loops — The Rust Reference: the exact rules for what a
forloop does behind the scenes. Iterator::step_by— standard library docs: howstep_byworks, with examples.revis documented on the same page.