Control flow refers to the order in which individual statements, instructions, or function calls of an imperative program are executed or evaluated. It dictates how your program makes decisions, repeats actions, and structures its logic. Without control flow, programs would simply execute statements from top to bottom, which is rarely sufficient for any practical application.
Rust, like many other programming languages, provides several constructs for controlling the flow of execution:
1. Conditional Expressions (`if`/`else if`/`else`): These allow your program to execute different blocks of code based on whether a specified condition evaluates to `true` or `false`. In Rust, `if` is an expression, meaning it can return a value.
* `if condition { ... }`: Executes code if the condition is true.
* `if condition { ... } else { ... }`: Provides an alternative block of code if the condition is false.
* `if condition1 { ... } else if condition2 { ... } else { ... }`: Allows for multiple conditions.
2. Looping Constructs (`loop`, `while`, `for`): These allow your program to repeatedly execute a block of code.
* `loop { ... }`: An infinite loop that continues executing its body repeatedly until explicitly told to stop using `break`. This loop can also return a value.
* `while condition { ... }`: Executes its body as long as the specified condition remains `true`. Once the condition becomes `false`, the loop terminates.
* `for element in collection { ... }`: Iterates over a sequence of elements (like a range, array, or vector). It's a safe and concise way to iterate, preventing off-by-one errors common with manual indexing.
3. Pattern Matching (`match`): Rust's `match` keyword is a powerful control flow operator that allows you to compare a value against a series of patterns and then execute code based on which pattern the value matches. It's exhaustive, meaning you must cover all possibilities, or explicitly use `_` for any unmatched cases. `match` is also an expression and returns a value.
4. Loop Control Keywords (`break`, `continue`):
* `break`: Immediately exits the innermost loop. When used with a labeled loop, it can exit outer loops.
* `continue`: Skips the rest of the current iteration of the loop and proceeds to the next iteration.
5. Return (`return`): The `return` keyword is used to exit a function and specify the value that the function should produce.
Rust's control flow constructs are flexible and powerful, especially with their ability to be expressions that return values, which can lead to more concise and functional code.
Example Code
fn main() {
println!("\n--- 1. If/Else If/Else ---");
let number = 7;
if number < 5 {
println!("Condition was true: number is less than 5");
} else if number == 5 {
println!("Condition was true: number is equal to 5");
} else {
println!("Condition was false: number is greater than 5");
}
// If as an expression
let condition = true;
let result = if condition {
5 // This is the value returned if condition is true
} else {
6 // This is the value returned if condition is false
};
println!("Result from if expression: {}", result);
println!("\n--- 2. Loop ---");
let mut counter = 0;
let loop_result = loop {
counter += 1;
println!("Loop iteration: {}", counter);
if counter == 10 {
break counter * 2; // break statement can return a value
}
};
println!("Loop exited. Loop result: {}", loop_result);
println!("\n--- 3. While Loop ---");
let mut countdown = 3;
while countdown != 0 {
println!("{}!", countdown);
countdown -= 1;
}
println!("LIFTOFF!!!");
println!("\n--- 4. For Loop ---");
let a = [10, 20, 30, 40, 50];
println!("Iterating over an array:");
for element in a.iter() {
println!("The value is: {}", element);
}
println!("Iterating over a range:");
for number in (1..4).rev() { // (1..4) is exclusive of 4, .rev() reverses it
println!("{}!", number);
}
println!("For loop finished!");
println!("\n--- 5. Match Expression ---");
let grade = 'A';
let message = match grade {
'A' => "Excellent!",
'B' => "Very good!",
'C' => "Good!",
'D' => "Pass",
'F' => "Fail",
_ => "Invalid grade", // The underscore _ is a catch-all pattern
};
println!("Your grade is '{}': {}", grade, message);
let lucky_number = 7;
match lucky_number {
1 => println!("One!"),
2 | 3 => println!("Two or Three!"), // Multiple patterns
4..=6 => println!("Between four and six (inclusive)!"), // Range pattern
_ => println!("Some other number!"), // Catch-all
}
// Match as an expression
let color_code = 2;
let color_name = match color_code {
1 => "Red",
2 => "Green",
3 => "Blue",
_ => "Unknown",
};
println!("Color code {} maps to: {}", color_code, color_name);
println!("\n--- 6. Continue & Break with labeled loops ---");
'outer_loop: loop {
println!("Entered outer loop");
let mut i = 0;
loop {
i += 1;
if i == 3 {
println!("Inner loop: Skipping iteration 3");
continue; // Skips to the next iteration of the inner loop
}
if i == 5 {
println!("Inner loop: Breaking outer loop from inner at iteration 5");
break 'outer_loop; // Breaks the 'outer_loop'
}
println!("Inner loop iteration: {}", i);
}
println!("This will not be printed after break 'outer_loop'");
}
println!("Exited outer loop");
}








Control Flow