Beginner Level
Control Flow
Chapter 4: Control Flow š
Control flow is how you make decisions and repeat actions in your programs. Rust provides several constructs for controlling the flow of execution.
If Expressions
Basic If
fn main() {
let number = 3;
if number < 5 {
println!("condition was true");
} else {
println!("condition was false");
}
}If-Else If
fn main() {
let number = 6;
if number % 4 == 0 {
println!("number is divisible by 4");
} else if number % 3 == 0 {
println!("number is divisible by 3");
} else if number % 2 == 0 {
println!("number is divisible by 2");
} else {
println!("number is not divisible by 4, 3, or 2");
}
}If in a Let Statement
Since if is an expression, you can use it on the right side of a let statement:
fn main() {
let condition = true;
let number = if condition { 5 } else { 6 };
println!("The value of number is: {}", number);
}Loops
Loop - Infinite Loop
fn main() {
let mut counter = 0;
let result = loop {
counter += 1;
if counter == 10 {
break counter * 2; // Return value from loop
}
};
println!("The result is {}", result);
}While Loop
fn main() {
let mut number = 3;
while number != 0 {
println!("{}!", number);
number -= 1;
}
println!("LIFTOFF!!!");
}For Loop
fn main() {
let a = [10, 20, 30, 40, 50];
for element in a {
println!("the value is: {}", element);
}
// Using ranges
for number in 1..4 {
println!("{}!", number);
}
// Inclusive range
for number in 1..=3 {
println!("{}!", number);
}
// Reverse countdown
for number in (1..4).rev() {
println!("{}!", number);
}
}Match Expression
Basic Match
fn main() {
let x = 1;
match x {
1 => println!("one"),
2 => println!("two"),
3 => println!("three"),
_ => println!("anything"),
}
}Match with Values
fn value_in_cents(coin: Coin) -> u8 {
match coin {
Coin::Penny => 1,
Coin::Nickel => 5,
Coin::Dime => 10,
Coin::Quarter => 25,
}
}
enum Coin {
Penny,
Nickel,
Dime,
Quarter,
}Match Guards
fn main() {
let num = Some(4);
match num {
Some(x) if x < 5 => println!("less than five: {}", x),
Some(x) => println!("{}", x),
None => (),
}
}If Let
For when you only care about one pattern:
fn main() {
let some_u8_value = Some(0u8);
// Instead of this verbose match:
match some_u8_value {
Some(3) => println!("three"),
_ => (),
}
// Use if let:
if let Some(3) = some_u8_value {
println!("three");
}
}Practical Examples
Example 1: Grade Calculator
fn get_letter_grade(score: u32) -> char {
match score {
90..=100 => 'A',
80..=89 => 'B',
70..=79 => 'C',
60..=69 => 'D',
_ => 'F',
}
}
fn main() {
let scores = [95, 87, 76, 65, 45];
for score in scores {
let grade = get_letter_grade(score);
println!("Score: {} -> Grade: {}", score, grade);
}
}Example 2: Number Guessing Game Logic
use std::cmp::Ordering;
fn check_guess(guess: u32, secret: u32) -> String {
match guess.cmp(&secret) {
Ordering::Less => "Too small!".to_string(),
Ordering::Greater => "Too big!".to_string(),
Ordering::Equal => "You win!".to_string(),
}
}
fn main() {
let secret_number = 42;
let guesses = [25, 50, 42, 30];
for guess in guesses {
let result = check_guess(guess, secret_number);
println!("Guess: {} -> {}", guess, result);
if guess == secret_number {
break;
}
}
}Practice Exercises
Exercise 1: FizzBuzz
Write a program that prints numbers 1-100, but:
- Print "Fizz" for multiples of 3
- Print "Buzz" for multiples of 5
- Print "FizzBuzz" for multiples of both
Exercise 2: Prime Number Checker
Write a function that checks if a number is prime:
fn is_prime(n: u32) -> bool {
// Your implementation here
}Exercise 3: Factorial Calculator
Write a function that calculates factorial using a loop:
fn factorial(n: u32) -> u32 {
// Your implementation here
}Loop Labels
For nested loops, you can use labels:
fn main() {
'outer: loop {
println!("Entered the outer loop");
'inner: loop {
println!("Entered the inner loop");
break 'outer;
}
println!("This point will never be reached");
}
println!("Exited the outer loop");
}Key Takeaways
- ā
ifis an expression that can return values - ā
loopcreates infinite loops,whilehas conditions,foriterates - ā
matchis powerful pattern matching (exhaustive) - ā
if letis syntactic sugar for simple matches - ā
Use ranges (
1..5,1..=5) for numeric iterations - ā Loop labels help with nested loop control
Ready for Chapter 5? ā Ownership and Borrowing