Control flow is a fundamental concept in programming that allows you to dictate the order in which statements and expressions are executed. In Rust, control flow is managed using conditional statements, loops, and pattern matching. This section will cover the following topics:

  1. Conditional Statements (if, else if, else)
  2. Looping Constructs (loop, while, for)
  3. Pattern Matching (match)

  1. Conditional Statements

Conditional statements allow you to execute code based on certain conditions. Rust provides the if, else if, and else keywords for this purpose.

if Statement

The if statement evaluates a condition and executes the associated block of code if the condition is true.

fn main() {
    let number = 5;

    if number > 0 {
        println!("The number is positive.");
    }
}

else if and else Statements

You can chain multiple conditions using else if and provide a fallback using else.

fn main() {
    let number = -3;

    if number > 0 {
        println!("The number is positive.");
    } else if number < 0 {
        println!("The number is negative.");
    } else {
        println!("The number is zero.");
    }
}

Using if in a let Statement

You can use if in a let statement to assign a value based on a condition.

fn main() {
    let condition = true;
    let number = if condition { 5 } else { 10 };

    println!("The number is: {}", number);
}

  1. Looping Constructs

Rust provides several ways to perform repetitive tasks: loop, while, and for.

loop

The loop keyword creates an infinite loop. You can break out of the loop using the break keyword.

fn main() {
    let mut count = 0;

    loop {
        count += 1;
        println!("Count: {}", count);

        if count == 5 {
            break;
        }
    }
}

while

The while loop runs as long as a condition is true.

fn main() {
    let mut number = 3;

    while number != 0 {
        println!("{}!", number);
        number -= 1;
    }

    println!("Liftoff!");
}

for

The for loop is used to iterate over a range or a collection.

fn main() {
    for number in 1..4 {
        println!("{}!", number);
    }

    println!("Liftoff!");
}

  1. Pattern Matching

Pattern matching in Rust is done using the match keyword. It allows you to compare a value against a series of patterns and execute code based on which pattern matches.

Basic match Example

fn main() {
    let number = 3;

    match number {
        1 => println!("One!"),
        2 => println!("Two!"),
        3 => println!("Three!"),
        _ => println!("Something else!"),
    }
}

Matching Multiple Patterns

You can match multiple patterns using the | operator.

fn main() {
    let number = 2;

    match number {
        1 | 2 => println!("One or Two!"),
        3 => println!("Three!"),
        _ => println!("Something else!"),
    }
}

Destructuring in match

You can also destructure complex data types in a match statement.

struct Point {
    x: i32,
    y: i32,
}

fn main() {
    let point = Point { x: 0, y: 7 };

    match point {
        Point { x: 0, y } => println!("On the y-axis at {}", y),
        Point { x, y: 0 } => println!("On the x-axis at {}", x),
        Point { x, y } => println!("On neither axis: ({}, {})", x, y),
    }
}

Practical Exercises

Exercise 1: FizzBuzz

Write a program that prints the numbers from 1 to 20. For multiples of three, print "Fizz" instead of the number, and for multiples of five, print "Buzz". For numbers that are multiples of both three and five, print "FizzBuzz".

fn main() {
    for number in 1..=20 {
        if number % 3 == 0 && number % 5 == 0 {
            println!("FizzBuzz");
        } else if number % 3 == 0 {
            println!("Fizz");
        } else if number % 5 == 0 {
            println!("Buzz");
        } else {
            println!("{}", number);
        }
    }
}

Exercise 2: Factorial

Write a function that calculates the factorial of a number using a while loop.

fn factorial(n: u32) -> u32 {
    let mut result = 1;
    let mut i = n;

    while i > 1 {
        result *= i;
        i -= 1;
    }

    result
}

fn main() {
    let number = 5;
    println!("The factorial of {} is {}", number, factorial(number));
}

Exercise 3: Fibonacci Sequence

Write a function that generates the first n numbers in the Fibonacci sequence using a for loop.

fn fibonacci(n: u32) -> Vec<u32> {
    let mut sequence = vec![0, 1];

    for i in 2..n {
        let next = sequence[i as usize - 1] + sequence[i as usize - 2];
        sequence.push(next);
    }

    sequence
}

fn main() {
    let n = 10;
    let sequence = fibonacci(n);
    println!("The first {} numbers in the Fibonacci sequence are: {:?}", n, sequence);
}

Conclusion

In this section, you learned about control flow in Rust, including conditional statements, looping constructs, and pattern matching. These tools allow you to control the execution of your code based on various conditions and patterns. Practice the exercises provided to reinforce your understanding and prepare for more advanced topics in Rust.

Rust Programming Course

Module 1: Introduction to Rust

Module 2: Basic Concepts

Module 3: Ownership and Borrowing

Module 4: Structs and Enums

Module 5: Collections

Module 6: Error Handling

Module 7: Advanced Concepts

Module 8: Concurrency

Module 9: Advanced Features

Module 10: Project and Best Practices

© Copyright 2024. All rights reserved