Start learning free

LESSON 128 OF 414 · WHILE LOOPS & FOR LOOPS

The For Loop in Rust: Iterating Over a Range

Lesson Read the full explanation

There is a more powerful way to use the for loop in Rust.

Rust has no three-part for (init; condition; update) loop. A for loop goes through every value of a range (or any other iterator), one value per iteration:

for i in range {
	instruction1;
	instruction2;
	...
}

Let's break down each component:

  • The loop variable (i) is created by the loop itself, with no let, and takes the next value from the range on every iteration.

  • The range (such as 0..4) says which values the variable takes: it starts at the first number and stops before the end number, which is excluded.

  • The loop stops by itself when the range runs out of values, and the variable moves to the next value automatically, so there is nothing to update.


Example:

for i in 0..4 {
	println!("Hello world!");
}

// This code prints "Hello world!" on four different lines

Let's break down this code:

  • The range 0..4 starts at 0, so the loop variable i starts counting from 0.

  • The range ends before 4, meaning the loop will run as long as the loop variable, i, is less than 4.

  • After each iteration, after running the code inside {}, i automatically moves to the next value, which is 1 larger.


This is what the computer does behind the scenes during this loop:

0. The loop creates the variable i and sets it to the first value of the range, i = 0

1. First iteration:
	a. Is i < 4 true? <=> Is 0 < 4 true? Yes.
	b. Run the code inside {}. Print "Hello world!".
	c. i moves to the next value => i = 1

2. Second iteration:
	a. Is i < 4 true? <=> Is 1 < 4 true? Yes.
	b. Run the code inside {}. Print "Hello world!".
	c. i moves to the next value => i = 2

3. Third iteration:
	a. Is i < 4 true? <=> Is 2 < 4 true? Yes.
	b. Run the code inside {}. Print "Hello world!".
	c. i moves to the next value => i = 3

4. Fourth iteration:
	a. Is i < 4 true? <=> Is 3 < 4 true? Yes.
	b. Run the code inside {}. Print "Hello world!".
	c. i moves to the next value => i = 4

5. Fifth iteration:
	a. Is i < 4 true? <=> Is 4 < 4 true? No.
	b. Exit the loop.

Assignment

Let's print "I promise to learn coding." 5 times using a for loop.


Hint
Look at the examples above if you get stuck.


STEP 1 OF 2
    Ctrl + Enter to check

    RUST · WHILE LOOPS & FOR LOOPS

    The For Loop in Rust, explained

    How Rust's for loop works

    In many languages a for loop has three parts in its header: a starting statement, a condition and an update. Rust's for loop does not. It takes a variable name and something it can iterate over, and runs the body once for each item that comes out:

    for i in range {
        // statements
    }

    The start, the end and the step are all carried by the thing after in. For counting, that is a range, and the loop variable receives one value from the range on every pass. You do not declare the variable with let, you do not test a condition and you do not write an update. All three are handled for you.

    Ranges

    A range is written with two dots. 0..4 produces 0, 1, 2 and 3. The start is included and the end is excluded. With an equals sign, 0..=4 includes the end as well and produces 0, 1, 2, 3 and 4.

    for i in 0..4 {
        println!("Hello world! {}", i);
    }

    This runs four times, with i equal to 0, 1, 2 and 3, and prints Hello world! 0 through Hello world! 3. A useful number to remember: for a..b the body runs b - a times, and for a..=b it runs b - a + 1 times (when b is not below a).

    What the for loop does for you

    Compare it with a while loop that does the same job:

    let mut i = 0;
    while i < 4 {
        println!("Hello world! {}", i);
        i += 1;
    }

    The while version has three separate places where a mistake can hide: the starting value, the condition and the update. The for version has one: the range. There is no way to forget the update, so a for loop over a range cannot run forever.

    The loop variable exists only inside the loop. Using i after the closing brace is a compile error, cannot find value i in this scope. It is also a fresh variable on each pass, so changing it inside the body does not change how the loop counts. Writing to it would need for mut i in ..., and the next value still comes from the range.

    The exercise, step by step

    The lesson asks for the message I promise to learn coding. printed five times using a for loop.

    1. Write the loop header with a variable i over the range 0..5. The range produces 0, 1, 2, 3 and 4, which is five values. Since the end is excluded, 0..5 is exactly right. Using 0..=5 would produce six values and print the message six times.
    2. Print the message inside the braces with println!. The body runs once per value, so one line of code prints the message five times.
    for i in 0..5 {
        println!("I promise to learn coding.");
    }

    The program prints the message on five lines.

    The unused variable warning

    The body never uses i, so Rust prints a warning, unused variable: i, and suggests naming it _i. It is only a warning, and the program still compiles and runs. When you do not need the number, you can write _ as the name, as in for _ in 0..5. That says "I do not need this value" and the warning goes away. The lesson's exercise keeps i, and the output is the same.

    Common mistakes

    • Mixing up .. and ..=. 0..5 runs five times and 0..=5 runs six times.
    • Looking for a condition or an update. There is none to write. If you need a different start, end or step, you change the range, or use methods on it, which the next lessons show.
    • Writing parentheses around the range out of habit from other languages. They are not needed (they are used later only for calling methods on a range).
    • Using the loop variable outside the loop. It no longer exists after the closing brace.
    • A backwards range. 5..0 is empty, so the body never runs. A Rust range only counts up.

    Key takeaways

    • for i in range { ... } runs the body once for each value in the range, with no counter to declare, test or update.
    • a..b excludes b and a..=b includes it.
    • A for loop over a range always finishes, because the range is finite.
    • Name the variable _ if the body does not use it.
    Keep going with RustAbout 340 step-by-step lessons, from your first line of code to coding interviews. Free to start.
    Start learning free