Start learning free

LESSON 118 OF 414 · FOR LOOPS - LOOPING OVER ARRAYS

For Loop Execution Flow in Rust: What Is Inside the Braces

Lesson Read the full explanation

Rust uses curly braces ({}) to indicate which lines of code are part of a for loop and which are not.

Take this code for example:

let languages = vec!["Python", "Java", "JavaScript"];

for language in &languages {
  println!("I love {}", language);
  println!("I want to get better at it");
}

Both println! statements are part of the loop since they are written inside the braces.

This means that both messages will be printed for every language in the languages vector. The output of that code would be:

I love Python
I want to get better at it
I love Java
I want to get better at it
I love JavaScript
I want to get better at it

As for this code:

let languages = vec!["Python", "Java", "JavaScript"];

for language in &languages {
  println!("I love {}", language);
}
println!("I want to get better at them");

The println!("I want to get better at them"); is not part of the loop.

This means that only println!("I love {}", language); will be executed for every language in the languages vector.

Then, when the for loop is over, the println!("I want to get better at them"); will be executed only once.

The output of this program would be:

I love Python
I love Java
I love JavaScript
I want to get better at them

Execution flow

Lastly, note that the execution of a program always begins on the first line. The code is then executed one line at a time from top to bottom. This is known as execution flow and is the order a program in Rust executes code.

For example, this program:

let fruits = vec!["banana", "apple", "kiwi"];

println!("I'm hungry!");

for fruit in &fruits {
  println!("I'm gonna eat:");
  println!("{}", fruit);
}


println!("I love my life!");

prints:

I'm hungry!
I'm gonna eat:
banana
I'm gonna eat:
apple
I'm gonna eat:
kiwi
I love my life!


Assignment:

Add a for loop inside our code in the editor such that the final program would print:

Today we'll learn about:
Python
Java
JavaScript
Let's code!
STEP 1 OF 1
    Ctrl + Enter to check

    RUST · FOR LOOPS - LOOPING OVER ARRAYS

    Exercise Create A For Loop in Rust, explained

    The braces decide what repeats

    A Rust for loop repeats whatever sits between its braces. Lines inside the braces form the loop body and run once for every item. Lines outside run on their own schedule: before the loop if they come before it, after it if they come after.

    Take this code:

    let languages = vec!["Python", "Java", "JavaScript"];
    
    for language in &languages {
        println!("I love {}", language);
        println!("I want to get better at it");
    }

    Both println! calls are inside the braces, so both run for every language:

    I love Python
    I want to get better at it
    I love Java
    I want to get better at it
    I love JavaScript
    I want to get better at it
    

    Now move the second print out of the loop:

    let languages = vec!["Python", "Java", "JavaScript"];
    
    for language in &languages {
        println!("I love {}", language);
    }
    println!("I want to get better at them");

    Only the first print is in the body. The second one runs once, after the loop has finished:

    I love Python
    I love Java
    I love JavaScript
    I want to get better at them
    

    Indentation helps you read this, but in Rust it doesn't decide anything. The compiler reads the braces. A line that is indented like the body but sits after the closing brace is still outside the loop.

    Execution flow

    A program starts at its first line and runs statements from top to bottom, one at a time. This order is called the execution flow. A loop doesn't break it. When the flow reaches a for, it runs the body once per item, then moves on to the line after the closing brace.

    Here is a longer example:

    let fruits = vec!["banana", "apple", "kiwi"];
    
    println!("I'm hungry!");
    
    for fruit in &fruits {
        println!("I'm gonna eat:");
        println!("{}", fruit);
    }
    
    println!("I love my life!");

    The flow is: print I'm hungry! once, run the body for banana, run it for apple, run it for kiwi, then print I love my life! once. The output shows it:

    I'm hungry!
    I'm gonna eat:
    banana
    I'm gonna eat:
    apple
    I'm gonna eat:
    kiwi
    I love my life!
    

    Each statement in the body appears three times, once per fruit, and the two outside statements appear once each. Counting this way is the habit to build: for every line, ask whether it is inside the braces or not.

    The exercise

    The editor holds this code, and the program should print four lines:

    Today we'll learn about:
    Python
    Java
    JavaScript
    Let's code!
    

    The first and last lines come from the existing println! statements. The three language names must come from a loop placed between them. The step is to add a for loop whose loop variable is named language and which iterates over &languages, a borrowed reference to the vector, so the vector stays usable after the loop. Inside it, print the variable with the format string "{}".

    The loop goes between the two prints because of the execution flow: the heading must come before the items, and the closing line after them. If you put the loop above the first print, the names would come out before the heading. The reference solution is:

    let languages = vec!["Python", "Java", "JavaScript"];
    println!("Today we'll learn about:");
    // Write the for loop below:
    for language in &languages {
        println!("{}", language)
    }
    println!("Let's code!");

    Details and common mistakes

    • The println! inside the loop has no semicolon in the reference. A semicolon is optional after the last statement of a block when its value is (), as it is here, and adding one is equally fine.
    • println! needs a format string. println!(language) doesn't work; write println!("{}", language).
    • Writing for language in languages without the & moves the vector into the loop, so it can't be used after it.
    • Placing the loop after println!("Let's code!") prints the languages last. The order of the lines in the code is the order of the output.

    Key takeaways

    • The braces of a for loop mark its body, and only the body repeats.
    • Code before the loop runs once before it, and code after the loop runs once after it.
    • Programs run top to bottom, and a loop just repeats a stretch of that flow.
    Keep going with RustAbout 340 step-by-step lessons, from your first line of code to coding interviews. Free to start.
    Start learning free