Start learning free

LESSON 119 OF 414 · FOR LOOPS - LOOPING OVER ARRAYS

Buggy Code: Loop Body vs Code Before the Loop in Rust

Practice Read the full explanation

Inside the code editor we've tried to write a program that should print:

I'm hungry!
I'll eat some pasta
I'll eat some burgers
I'll eat some pizza

but it seems like we made some mistakes because when we run our code, it produces this output:

I'm hungry!
I'll eat some pasta
I'm hungry!
I'll eat some burgers
I'm hungry!
I'll eat some pizza

Assignment:

Your task is to fix our code such that it will print the desired output.

STEP 1 OF 1
    Ctrl + Enter to check

    RUST · FOR LOOPS - LOOPING OVER ARRAYS

    Buggy Code For Loops Execution Flow 1 in Rust, explained

    Problem overview

    The program should announce that you are hungry once, then list the foods:

    I'm hungry!
    I'll eat some pasta
    I'll eat some burgers
    I'll eat some pizza
    

    The code in the editor compiles and runs, but its output repeats the first line:

    I'm hungry!
    I'll eat some pasta
    I'm hungry!
    I'll eat some burgers
    I'm hungry!
    I'll eat some pizza
    

    This is the starting code:

    let foods = vec!["pasta", "burgers", "pizza"];
    
    for food in &foods {
        println!("I'm hungry!");
        println!("I'll eat some {}", food);
    }

    What goes wrong

    Every statement between the loop's braces runs once for each item in the vector. The vector has three foods, so the body runs three times, and both println! calls run on every pass. That is exactly the output you see: a hunger announcement before each food.

    Nothing is wrong with the food lines. The problem is the placement of the first print. I'm hungry! describes the whole meal, not any single food, so it belongs outside the loop.

    How to decide where a statement belongs

    For each statement, ask how many times it should happen:

    • Once per item: put it inside the braces. The food line uses food and changes with every pass, so it belongs inside.
    • Once for the whole task, before the items: put it before the for.
    • Once for the whole task, after the items: put it after the closing brace.

    The announcement must happen once, and before the first food. So it moves above the loop.

    Tracing both versions

    A quick way to see the difference is to write down the order in which the lines run. In the buggy version the flow is: declare the vector, then for pasta print the announcement and the food, for burgers print the announcement and the food, for pizza print the announcement and the food. That is six prints from two statements, three each.

    In the fixed version the flow is: declare the vector, print the announcement, then for pasta, burgers and pizza print the food. That is one announcement and three food lines, four prints in total. The count of prints is the loop's item count times the statements in the body, plus the statements outside it.

    The fix, step by step

    1. Remove println!("I'm hungry!"); from inside the loop's braces.
    2. Write it again on the line before for, after the vector is declared.
    3. Leave the food line inside the loop, unchanged.

    The reference solution is:

    let foods = vec!["pasta", "burgers", "pizza"];
    println!("I'm hungry!");
    for food in &foods {
        println!("I'll eat some {}", food);
    }

    The flow is: declare the vector, print the announcement once, run the body for pasta, burgers and pizza, and finish. The output matches the expected four lines.

    Details and common mistakes

    • Deleting the announcement instead of moving it. The program then prints only the three food lines.
    • Moving it to after the loop. It then prints last, which gives the right count of lines but the wrong order.
    • Changing the food line when only the placement of the other print was wrong.
    • Indentation is not what decides this. In Rust the braces do. A line that is indented like the body but sits after the closing brace is outside the loop, and a line inside the braces is in the loop whatever its indentation.

    Testing

    Add a fourth food to the vector, for example "salad". In the fixed program the output gains one line, I'll eat some salad, and I'm hungry! still appears exactly once. In the buggy version it would have appeared four times. If you can predict how many times each line prints after changing the vector, you have understood the execution 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