Rust by Example: Control Flow
Rust 1.75+
Master the flow of execution in your Rust programs. This guide covers 'if' expressions, unconditional 'loop' cycles, 'while' loops, and the idiomatic 'for' loop for iterating over collections safely and efficiently.
Code
fn main() {
// --- if Expressions ---
let number = 6;
// 'if' is an expression, so it returns a value!
let condition = true;
let number = if condition { 5 } else { 6 };
println!("The value of number is: {}", number);
// --- loop (infinite) ---
let mut counter = 0;
let result = loop {
counter += 1;
if counter == 10 {
// You can break with a value
break counter * 2;
}
};
println!("Loop result: {}", result);
// --- while loop ---
let mut n = 3;
while n != 0 {
println!("{}!", n);
n -= 1;
}
println!("LIFTOFF!!!");
// --- for loop (iterators) ---
let a = [10, 20, 30, 40, 50];
// Best practice: iterate over collection
for element in a.iter() {
println!("the value is: {}", element);
}
// Range based for loop
// (1..4) is 1, 2, 3. (1..=4) is 1, 2, 3, 4.
for number in (1..4).rev() {
println!("{}...", number);
}
}Explanation
Control flow in Rust will feel familiar to C or Java developers, but with a few functional twists. The most significant difference is that if is an expression, not just a statement. This means if blocks return a value, allowing you to assign the result of an if-else chain directly to a variable (similar to the ternary operator ? : in other languages, but more general).
Rust provides three types of loops:
- loop: Creates an infinite loop. Unique because it can return a value using
break value;, which is handy for retry logic that needs to produce a result. - while: Standard conditional looping. It runs while the condition is true.
- for: The most powerful and idiomatic way to iterate. It works with any type that implements the
Iteratortrait. Usingforwith a collection is safer and faster than a C-style loop with an index, as it eliminates bounds checks and off-by-one errors.
Code Breakdown
7
let number = if condition { 5 } else { 6 };. Because if is an expression, we can use it on the right side of a let statement. Note the lack of semicolons inside the blocks; this makes them return the value.16
break counter * 2;. We are breaking out of the infinite loop and returning the value 20. This value is then assigned to the variable result.39
(1..4).rev(). Ranges are first-class citizens in Rust. 1..4 generates numbers 1, 2, 3. The .rev() method reverses the iterator, so this loop counts down.
