6  for-loops

Objective

Be able to iterate over a collection of values. Apply logic inside of the for loop.

for loop syntax

In Rust, for loops are the easiest way to go over each item in a vector or array.

for value in collection {
    // do something with value
}

When we iterate through a collection, each item takes on the value of the name you provide before in. For example for x in my_vec creates a binding to x at each iteration.

fn main() {
    let nums = vec![1, 2, 3];
    for n in nums {
        println!("n is: {}", n);
    }
}

Scope

R has some of the most flexible and unique scoping rules. Rust isn’t as kind. The rules are essentially:

  • Values outside of the for loop are accessible inside of it.
  • Values created inside of the for loop cannot be accessed outside of it.

Example: Outer value used inside loop

This does compile
fn main() {
    let greeting = "Hi";
    let names = vec!["Alice", "Bob"];

    for name in names {
        println!("{greeting}, {name}!");
    }
}

Example: Inner value not usable outside loop

This does not compile!
fn main() {
    let numbers = vec![1, 2, 3];

    for n in numbers {
        let doubled = n * 2;
        println!("{n} doubled is {doubled}");
    }

    // ❌ `doubled` doesn't exist here
    // println!("Last doubled: {}", doubled);
}

Exercise

Using a vector of integers, write a loop that prints:

  • “Fizz” if divisible by 3
  • “Buzz” if divisible by 5
  • “FizzBuzz” if divisible by both
  • The number otherwise

Use this vector: vec![1, 2, 3, 4, 5, 15]

Solution

View hint
fn main() {
    let nums = vec![1, 2, 3, 4, 5, 15];

    for n in nums {
       // add fizz-buzz logic here referring to `n`
    }
}
View solution
fn main() {
    let nums = vec![1, 2, 3, 4, 5, 15];

    for n in nums {
        if n % 15 == 0 {
            println!("FizzBuzz");
        } else if n % 3 == 0 {
            println!("Fizz");
        } else if n % 5 == 0 {
            println!("Buzz");
        } else {
            println!("{}", n);
        }
    }
}