Decision-making in Rust involves controlling the flow of execution based on conditions.
Rust provides constructs like if, else if, else, match, and loops with conditions to implement decision-making logic effectively.
In this tutorial, we will cover:
1. Using if Statements
The if statement executes a block of code if the condition evaluates to true.
Example: Basic if
fn main() { let number = 10; if number > 5 { println!("The number is greater than 5."); } }
2. Combining if with else
The else block runs when the if condition is false.
Example: if and else
fn main() { let number = 3; if number % 2 == 0 { println!("The number is even."); } else { println!("The number is odd."); } }
3. Using else if for Multiple Conditions
The else if block checks additional conditions.
Example: if, else if, and else
fn main() { let score = 85; if score >= 90 { println!("Grade: A"); } else if score >= 80 { println!("Grade: B"); } else if score >= 70 { println!("Grade: C"); } else { println!("Grade: F"); } }
4. Conditional Expressions
In Rust, if can be used as an expression to assign a value to a variable.
Example: if as an Expression
fn main() { let age = 20; let category = if age >= 18 { "Adult" } else { "Minor" }; println!("Category: {}", category); }
5. The match Statement
The match statement is a powerful control flow construct that matches a value against multiple patterns.
Example: Using match
fn main() { let day = 3; match day { 1 => println!("Monday"), 2 => println!("Tuesday"), 3 => println!("Wednesday"), 4 => println!("Thursday"), 5 => println!("Friday"), 6 | 7 => println!("Weekend"), // Combine patterns _ => println!("Invalid day"), // Catch-all case } }
6. Using match with Enums
Enums and match are frequently used together to handle multiple cases.
Example: Matching Enums
enum TrafficLight { Red, Yellow, Green, } fn main() { let light = TrafficLight::Red; match light { TrafficLight::Red => println!("Stop"), TrafficLight::Yellow => println!("Slow down"), TrafficLight::Green => println!("Go"), } }
7. Pattern Matching
Rust's match statement supports complex patterns such as ranges, destructuring, and guards.
7.1 Ranges in match
fn main() { let number = 42; match number { 0..=10 => println!("The number is between 0 and 10"), 11..=50 => println!("The number is between 11 and 50"), _ => println!("The number is greater than 50"), } }
7.2 Destructuring in match
struct Point { x: i32, y: i32, } fn main() { let point = Point { x: 10, y: 20 }; match point { Point { x, y: 20 } => println!("x: {}, y is 20", x), Point { x, y } => println!("x: {}, y: {}", x, y), } }
7.3 Guards in match
fn main() { let number = 15; match number { n if n % 2 == 0 => println!("The number {} is even", n), n if n % 2 != 0 => println!("The number {} is odd", n), _ => println!("Unknown number"), } }
8. Practical Examples
8.1 Checking Leap Year
fn main() { let year = 2024; if year % 4 == 0 { if year % 100 != 0 || year % 400 == 0 { println!("{} is a leap year.", year); } else { println!("{} is not a leap year.", year); } } else { println!("{} is not a leap year.", year); } }
8.2 Categorizing Numbers
fn main() { let number = 15; match number { 0 => println!("Zero"), 1..=9 => println!("Single-digit number"), 10..=99 => println!("Double-digit number"), _ => println!("Large number"), } }
8.3 Command-Line Arguments with match
use std::env; fn main() { let args: Vec<String> = env::args().collect(); match args.len() { 1 => println!("No arguments provided."), 2 => println!("One argument: {}", args[1]), _ => println!("Multiple arguments: {:?}", &args[1..]), } }
8.4 Simplified Calculator
fn main() { let a = 10; let b = 5; let operator = '+'; let result = match operator { '+' => a + b, '-' => a - b, '*' => a * b, '/' => a / b, '%' => a % b, _ => { println!("Invalid operator"); return; } }; println!("Result: {}", result); }
9. Summary
Construct | Use Case |
---|---|
if | For simple decision-making based on a single condition. |
else if | For handling multiple conditions. |
else | For a default case when all other conditions are false. |
match | For matching values against multiple patterns, often replacing complex if-else chains. |
Guards | Adding conditions to patterns for more refined matches. |
Key Points
- Rust's decision-making constructs ensure safety and expressiveness.
- The match statement is powerful and versatile, especially when working with enums and patterns.
- Rust encourages exhaustive matches to handle all possible cases.
Practice with these examples to master decision-making in Rust!