DaleSchool

Conditionals and Loops

Beginner20min

Learning Objectives

  • Use if/else to execute different code based on conditions
  • Create infinite loops with loop and exit them with break
  • Iterate over ranges and collections with for loops
  • Use if as an expression to assign values to variables

Working Code

Try running the code below in the Rust Playground!

fn main() {
    let temperature = 30;

    if temperature >= 30 {
        println!("It's hot! Let's go grab an iced coffee ☕");
    } else if temperature >= 20 {
        println!("Perfect weather!");
    } else {
        println!("Bundle up, it's cold!");
    }

    // Print 1 through 5
    for i in 1..=5 {
        println!("Iteration {i}!");
    }
}

You write a condition after if, and the code inside {} runs when the condition is true. Unlike C or Java, you don't need parentheses around the condition.

for iterates over a range. 1..=5 means 1 through 5 (inclusive), while 1..5 means 1 through 4.

Try It Yourself

  1. Change temperature to 15. What message do you get?
  2. Change 1..=5 to 0..3. How many times does it loop?

"Why?" — if Can Produce a Value

Rust's if has something special compared to other languages. It's an expression that returns a value!

fn main() {
    let score = 85;
    let grade = if score >= 90 {
        "A"
    } else if score >= 80 {
        "B"
    } else {
        "C"
    };

    println!("Score: {score}, Grade: {grade}");
}

Pretty neat, right? You can assign the result of an if directly to a variable. The last value in each branch becomes the return value. Notice there's no semicolon (;) — the same rule as returning values from functions.

Rust has three kinds of loops.

| Loop | When to use it | | ------- | ---------------------------------------------------- | | for | When the number of iterations is known (most common) | | while | When you want to repeat while a condition is true | | loop | Infinite loop + exit with break |

fn main() {
    // while: repeat while the condition is true
    let mut count = 3;
    while count > 0 {
        println!("{count}!");
        count -= 1;
    }
    println!("Liftoff!");

    // loop: infinite loop + break
    let mut sum = 0;
    loop {
        sum += 1;
        if sum >= 10 {
            break;
        }
    }
    println!("Total: {sum}");
}

Deep Dive

What's the difference between while and loop?

while checks the condition first, then repeats. loop runs unconditionally and you exit with break.

loop has a special trick — you can attach a value to break to return it!

fn main() {
    let mut counter = 0;
    let result = loop {
        counter += 1;
        if counter == 5 {
            break counter * 10; // Returns 50
        }
    };
    println!("Result: {result}");
}

You can't do this with for or while. When you need to find a value while looping, loop is the way to go.

continue — Skip ahead

If break stops the loop entirely, continue skips just the current iteration and moves on to the next one.

fn main() {
    for i in 1..=10 {
        if i % 3 == 0 {
            continue; // Skip multiples of 3
        }
        println!("{i}");
    }
}

Run this and you'll see it prints everything except 3, 6, and 9.

There's an important rule when using if as an expression: every branch must return the same type.

fn main() {
    let value = if true {
        5
    } else {
        "hello" // Error! i32 and &str are different types
    };
}

Error message:

error[E0308]: `if` and `else` have incompatible types
 --> src/main.rs:4:9
  |
2 |       let value = if true {
  |  _________________-
3 | |         5
  | |         - expected because of this
4 | |     } else {
5 | |         "hello"
  | |         ^^^^^^ expected integer, found `&str`

What this means: "The types in if and else don't match." One branch is a number and the other is a string — Rust doesn't know what type to store. Make both branches return the same type and you're good.

  1. Implement FizzBuzz for numbers 1 through 100.
    • Print "Fizz" for multiples of 3
    • Print "Buzz" for multiples of 5
    • Print "FizzBuzz" for multiples of both 3 and 5
    • Print the number otherwise
    • Hint: use % for the remainder, and check the "both" condition first!
  2. Print the multiplication table from 2 to 9 using nested for loops. (for dan in 2..=9 { for i in 1..=9 { ... } })

Q1. What is the output of this code?

fn main() {
    let x = 7;
    let label = if x % 2 == 0 { "even" } else { "odd" };
    println!("{label}");
}
  • A) even
  • B) odd
  • C) Compilation error
  • D) No output

Q2. How many times does for i in 0..5 iterate?

  • A) 4 times
  • B) 5 times
  • C) 6 times
  • D) Infinite

Q3. What keyword do you use to stop a loop?

  • A) stop
  • B) exit
  • C) break
  • D) return