Skip to Content
Course content

9: Loops: loop, while, for

Click on the "Edit" button in the top corner of the screen to edit your slide content.

Why is there a specific loop keyword instead of just using while true?

If you're coming from C++ or Java, your instinct is probably to just write while true { ... }. While that works in Rust, the loop keyword is there for a very specific reason: it tells the compiler that this block is intended to run forever unless a break is hit.

The real magic happens with type checking. If you use while true, the compiler isn't always sure if the loop will ever terminate. With loop, the compiler knows for a fact that any code following the loop is unreachable unless there's a break. I usually reach for loop when I'm building things like a main game loop or a server listener where the loop is the primary driver of the application.

Can I actually get a value out of a loop?

This is one of my favorite "hidden" features of Rust. You can actually use break to return a value from a loop block and assign it to a variable. You can't do this with while or for loops, which is another reason why loop is so powerful.

Imagine you're polling a sensor or waiting for a specific piece of data from a network socket. Instead of declaring a mutable variable outside the loop and updating it inside, you can just do this:

fn find_ready_signal() -> bool {
    let signal = loop {
        if check_sensor() == "READY" {
            break true; // We found it! Return true from the loop
        }
        if check_sensor() == "ERROR" {
            break false; // Something went wrong, return false
        }
        // Just keep waiting...
    };

    signal // Now we use the value the loop gave us
}

Why doesn't Rust have the classic for(i=0; i<10; i++) syntax?

I know it feels weird at first, but Rust ditches the C-style for loop to avoid those annoying "off-by-one" errors we've all spent hours debugging. Instead, Rust uses iterators. When you write for i in 0..10, you're actually creating a Range object that the loop iterates over.

If you need the index and the value from a collection, don't try to manage a counter manually. Use the .enumerate() method. It's cleaner and much harder to mess up:

let tasks = vec!["Clean room", "Write code", "Buy milk"];

for (index, task) in tasks.iter().enumerate() {
    println!("Task #{}: {}", index + 1, task);
}

I've found that once you get used to this, going back to manual index management feels like walking a tightrope without a net.

When should I use while let instead of a standard while loop?

You'll see while let a lot in professional Rust code. It's essentially a shorthand for "keep looping as long as this pattern matches." It's incredibly useful when you're dealing with Option or Result types.

For example, if you have a Vec acting as a stack and you want to process it until it's empty, while let is your best friend:

let mut stack = vec![1, 2, 3];

// Keep popping values as long as pop() returns Some(value)
while let Some(top) = stack.pop() {
    println!("Processing: {}", top);
}
// The loop automatically stops when pop() returns None

Using a standard while here would require you to manually check stack.is_empty() and then call .unwrap() or handle the None case inside the loop, which is just extra boilerplate you don't need.




πŸ“‹ Practical Task

Build a Robust Retry-Logic System

You are writing a piece of software that needs to fetch a configuration file from a remote server. However, the server is "flaky"β€”it often fails before finally succeeding. Your goal is to implement a retry mechanism using the loops you've learned.

Requirements:

  • Create a function fetch_config() that randomly returns either Ok("Config Data") or Err("Connection Failed").
  • In your main function, use a loop to attempt to call fetch_config().
  • If the call fails, print a warning and increment a retry counter.
  • If the call succeeds, break the loop and return the successful data.
  • If the retry counter reaches 5 attempts without success, break the loop and print a final "Maximum retries reached" error message.
  • Use the loop's ability to return a value to store the final result (either the config data or a failure message) into a variable before printing it to the console.
Rating
0 0

There are no comments for now.

to be the first to leave a comment.