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
foodand 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
- Remove
println!("I'm hungry!");from inside the loop's braces. - Write it again on the line before
for, after the vector is declared. - 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.
