Code of the Day
BeginnerCore syntax

Control flow

Branch with if/else, repeat with loop, while, and for, and use Rust's range syntax to iterate precisely.

RustBeginner10 min read
Recommended first
By the end of this lesson you will be able to:
  • Write if/else branches and use if as an expression
  • Use loop, while, and for for the three forms of iteration
  • Iterate over a range with .. and ..=
  • Break out of a loop and return a value from it

The three universal shapes of logic — sequence, selection, iteration — look similar in Rust to what you've seen in other languages, with two Rust-specific twists worth knowing: if is an expression, and there are three distinct loop forms for three distinct situations.

if / else

let temperature = 22;

if temperature > 30 {
    println!("hot");
} else if temperature > 15 {
    println!("pleasant");
} else {
    println!("cold");
}

Note: Rust does not put parentheses around the condition — that would be a warning. The braces around each block are mandatory.

if as an expression

Because if is an expression, you can use it on the right side of a let:

let label = if temperature > 30 { "hot" } else { "not hot" };
println!("{}", label);

Both branches must have the same type. If they don't, the compiler will tell you — this is the same rule that applies to function return types.

This replaces the ternary operator. Languages like Python ("hot" if temp > 30 else "not hot") and JavaScript (temp > 30 ? "hot" : "not hot") have a special ternary operator. Rust doesn't need one — if already does the job because everything is an expression.

loop — repeat until you break

loop runs forever until you hit break. Use it when you know you need to run at least once, or when the exit condition is in the middle of the loop body:

let mut count = 0;
loop {
    count += 1;
    if count == 5 {
        break;
    }
}
println!("count is {}", count);  // count is 5

You can also return a value from a loop by putting it after break:

let mut attempts = 0;
let result = loop {
    attempts += 1;
    if attempts == 3 {
        break attempts * 2;   // loop evaluates to 6
    }
};
println!("result: {}", result);  // result: 6

while — condition-driven repetition

let mut n = 3;
while n > 0 {
    println!("{}!", n);
    n -= 1;
}
println!("Go!");

Use while when you have a condition to check at the top of each iteration, but you don't know how many iterations you'll need.

The classic infinite-loop bug: a while whose condition never becomes false. Every while loop should have a clear line that moves it toward stopping — look for it whenever you write one.

for — iterating over collections and ranges

for is the workhorse. Loop over any collection or range:

let names = ["Ada", "Alan", "Grace"];
for name in names {
    println!("Hello, {}!", name);
}

Ranges

Two forms you'll use constantly:

for i in 0..5 {    // 0, 1, 2, 3, 4 — exclusive end
    print!("{} ", i);
}
// 0 1 2 3 4

for i in 0..=5 {   // 0, 1, 2, 3, 4, 5 — inclusive end
    print!("{} ", i);
}
// 0 1 2 3 4 5

.. is the exclusive range (stops before the end). ..= is the inclusive range (includes the end). The exclusive form matches how indexing works — 0..n gives you the n valid indices of a collection of length n.

Check your understanding

Knowledge check

  1. 1.
    What must be true about the two branches of an if expression used in a let binding?
  2. 2.
    How many iterations does for i in 0..4 produce?
  3. 3.
    Which Rust loop form is most appropriate when you need to run a block at least once and the exit condition is determined inside the body?

Do it yourself

Write a program in src/main.rs that uses a for loop with a range to print the multiplication table for 7 (i.e., 7 x 1 through 7 x 10). Then refactor it into a function that takes the multiplier as a parameter.

cargo run
# should print:
# 7 x 1 = 7
# 7 x 2 = 14
# ...
# 7 x 10 = 70

Where to go next

You can express any logic with the tools you have now. Next: ownership basics — the concept that makes Rust different from every other mainstream language, and the foundation of its memory-safety guarantees.

Finished reading? Mark it complete to track your progress.

On this page