Rust - Control Flow
Rust provides several control flow statements to manage the flow of your program, allowing for branching,
looping, and pattern matching. These statements include if
, else
, match
,
loop
, while
, for
, and others. Here's a detailed overview of each:
1. if
Statement
The if
statement is used to execute code based on a condition. The condition must evaluate to a
boolean (true
or false
).
Basic if
rustfn main() {
let number = 7;
if number < 5 {
println!("The number is less than 5");
} else {
println!("The number is 5 or greater");
}
}
if
with else if
and else
You can chain multiple conditions using else if
, and provide a fallback with else
.
rustfn main() {
let number = 6;
if number % 4 == 0 {
println!("The number is divisible by 4");
} else if number % 3 == 0 {
println!("The number is divisible by 3");
} else if number % 2 == 0 {
println!("The number is divisible by 2");
} else {
println!("The number is not divisible by 4, 3, or 2");
}
}
if
as an Expression
In Rust, if
can be used as an expression to return a value.
rustfn main() {
let condition = true;
let number = if condition { 5 } else { 6 };
println!("The value of number is: {}", number);
}
2. match
Statement
The match
statement allows you to branch based on the value of a variable, matching it against
different patterns.
Basic match
rustfn main() {
let number = 3;
match number {
1 => println!("One"),
2 => println!("Two"),
3 => println!("Three"),
_ => println!("Other"), // `_` is a catch-all pattern
}
}
Matching Multiple Patterns
You can match multiple patterns using the |
operator.
rustfn main() {
let number = 2;
match number {
1 | 2 | 3 => println!("One, two, or three"),
_ => println!("Other"),
}
}
Matching Ranges
Rust allows you to match a range of values using ..=
.
rustfn main() {
let number = 7;
match number {
1..=5 => println!("Between 1 and 5"),
6..=10 => println!("Between 6 and 10"),
_ => println!("Outside the range"),
}
}
3. Looping Statements
Rust offers three main types of loops: loop
, while
, and for
.
Infinite Loop with loop
The loop
keyword creates an infinite loop that continues until you explicitly exit it with
break
.
rustfn main() {
let mut counter = 0;
loop {
counter += 1;
println!("Counter: {}", counter);
if counter == 10 {
break;
}
}
}
Conditional Loop with while
The while
loop runs as long as a condition remains true.
rustfn main() {
let mut number = 3;
while number != 0 {
println!("{}!", number);
number -= 1;
}
println!("Liftoff!");
}
Iterating with for
The for
loop is used to iterate over a collection or a range of numbers.
rustfn main() {
let a = [10, 20, 30, 40, 50];
for element in a.iter() {
println!("The value is: {}", element);
}
for number in 1..4 {
println!("{}!", number);
}
println!("Liftoff!");
}
4. break
and continue
Statements
break
: Exits the loop entirely.continue
: Skips the remaining code in the current iteration and moves to the next iteration.
Using break
and continue
rustfn main() {
for number in 1..10 {
if number == 5 {
continue; // Skip the rest of this loop iteration
}
if number == 8 {
break; // Exit the loop
}
println!("{}", number);
}
}
5. Loop Labels
Loop labels allow you to specify which loop to break
or continue
in a nested loop
situation.
Using Loop Labels
rustfn main() {
'outer: for i in 1..=3 {
for j in 1..=3 {
if i == 2 && j == 2 {
break 'outer; // Exit the outer loop
}
println!("i = {}, j = {}", i, j);
}
}
}
6. return
Statement
The return
statement is used to exit a function and optionally return a value.
Basic return
rustfn main() {
println!("Result: {}", add(5, 3));
}
fn add(a: i32, b: i32) -> i32 {
return a + b;
// Or simply:
// a + b
}
Summary
if
statements: For branching based on conditions.match
statements: For more complex pattern-based branching.- Looping statements:
loop
: For infinite loops with manual exit.while
: For conditional loops.for
: For iterating over collections or ranges.
break
andcontinue
: For controlling loop execution.- Loop labels: For managing nested loops.
return
statement: For exiting a function and returning a value.
These control statements form the backbone of how Rust programs handle flow and decision-making, allowing for complex and efficient execution paths.