Skip to content
DocsRust LearningbeginnerControl Flow
Chapter 3 of 19·beginner·6 min read

Control Flow

Luồng Điều Khiển

Conditionals, loops, and match expressions

Hover or tap any paragraph to see Vietnamese translation

The if/else Expression

The if expression lets you branch code depending on conditions. Unlike many other languages, if in Rust is an expression — it returns a value and can be used on the right side of a let statement.

src/main.rs
1fn main() {2    let number = 7;34    if number < 5 {5        println!("condition was true");6    } else {7        println!("condition was false");8    }910    // else if for multiple conditions11    if number % 4 == 0 {12        println!("divisible by 4");13    } else if number % 3 == 0 {14        println!("divisible by 3");15    } else if number % 2 == 0 {16        println!("divisible by 2");17    } else {18        println!("not divisible by 4, 3, or 2");19    }20}
Warning
The condition in if must be of type bool. Rust will not automatically convert other types to bool as JavaScript or Python would. Writing "if number { ... }" causes a compile error.

Using if in a let Statement

Because if is an expression, you can use it on the right side of a let statement to assign a value directly. Both arms must return the same data type — otherwise the compiler reports an error.

src/main.rs
1fn main() {2    let condition = true;34    // Both arms return i32 — this works5    let number = if condition { 5 } else { 6 };6    println!("The number is: {number}");78    // This would be a compile ERROR — mismatched types:9    // let number = if condition { 5 } else { "six" };10    //                            ^i32      ^&str — types must match1112    // Useful for concise conditional assignment13    let is_even = |n: i32| if n % 2 == 0 { "even" } else { "odd" };14    println!("7 is {}", is_even(7));15    println!("8 is {}", is_even(8));16}

Infinite Loops with loop

The loop keyword executes a block of code repeatedly until you explicitly exit with break. It is commonly used when retrying an operation that might fail, or when the stopping condition must be checked mid-body. loop can also return a value through break.

src/main.rs
1fn main() {2    let mut counter = 0;34    // loop can return a value via break5    let result = loop {6        counter += 1;78        if counter == 10 {9            break counter * 2; // the loop evaluates to 2010        }11    };12    println!("The result is: {result}"); // 20
Tip
loop can return a value through break. For example, "break counter * 2" makes the entire loop expression evaluate to counter * 2. This avoids declaring a mutable variable outside the loop just to store a result.

The while Loop

The while loop executes code while a condition remains true. It combines loop, if, else, and break — Rust provides the while construct to express this clearly and concisely.

src/main.rs
1fn main() {2    let mut number = 3;34    while number != 0 {5        println!("{number}!");6        number -= 1;7    }8    println!("LIFTOFF!!!");910    // Looping through a collection with while (less idiomatic in Rust)11    let a = [10, 20, 30, 40, 50];12    let mut index = 0;1314    while index < a.len() {15        println!("a[{index}] = {}", a[index]);16        index += 1;17    }18}
Info
Using while with an index to loop through an array is less efficient and more error-prone than using a for loop. The compiler cannot verify at compile time that the index is always within valid bounds.

The for Loop and Ranges

The for loop is the most common and preferred way to iterate over collections in Rust. It is safer than while (no risk of index errors) and often faster because the compiler can optimize it better.

src/main.rs
1fn main() {2    let a = [10, 20, 30, 40, 50];34    // Iterate over a collection5    for element in a {6        println!("the value is: {element}");7    }89    // Range: 1..4 means 1, 2, 3 (exclusive end)10    for number in 1..4 {11        println!("{number}");12    }

Loop Labels and Breaking with Values

With nested loops, break and continue apply to the innermost loop by default. To break out of or continue an outer loop, use loop labels — defined with a single quote prefix before the label name.

src/main.rs
1fn main() {2    let mut count = 0;34    'counting_up: loop {5        println!("count = {count}");6        let mut remaining = 10;78        loop {9            println!("  remaining = {remaining}");10            if remaining == 9 {11                break; // breaks the inner loop only12            }

The match Expression

match is a very powerful control flow construct in Rust that compares a value against a series of patterns and executes code for the first matching pattern. The compiler ensures all cases are handled (exhaustive matching).

src/main.rs
1fn main() {2    let number = 7;34    match number {5        1 => println!("one"),6        2 | 3 | 5 | 7 | 11 => println!("a prime"),7        13..=19 => println!("a teen"),8        _ => println!("something else"), // _ is the catch-all pattern9    }1011    // match is an expression — it returns a value12    let description = match number {
Info
match in Rust must handle all possible cases (exhaustive). If any case is missing, the compiler reports an error. The _ pattern is the catch-all — similar to default in a C/Java switch statement.

The if let and while let Syntax

if let is more concise syntax when you only want to match one pattern and ignore all other cases. It is less verbose than match but loses exhaustive checking. while let allows a loop to continue as long as a pattern keeps matching.

src/main.rs
1fn main() {2    let config_max: Option<u8> = Some(3u8);34    // Using match (verbose when you only care about one case)5    match config_max {6        Some(max) => println!("The maximum is {max}"),7        _ => (),8    }910    // if let — concise equivalent of the match above11    if let Some(max) = config_max {12        println!("The maximum is {max}");
Tip
Use if let when you only care about a single case and want concise code. When handling multiple different cases, use match so the compiler can ensure you have not missed any.

Key Takeaways

Điểm Chính

  • if/else expressions can return values in RustBiểu thức if/else có thể trả về giá trị trong Rust
  • Rust has three loop types: loop, while, and forRust có ba loại vòng lặp: loop, while và for
  • match must cover all possible patterns (exhaustive)match phải bao phủ tất cả các mẫu có thể (toàn diện)
  • for loops with iterators are the most idiomatic loop patternVòng lặp for với iterator là mẫu vòng lặp thông dụng nhất

Practice

Test your understanding of this chapter

Quiz

In Rust, what type must the condition in an if expression be?

Trong Rust, kiểu dữ liệu của điều kiện trong biểu thức if phải là gì?

True or False

The match expression in Rust requires handling all possible cases (exhaustive matching).

Biểu thức match trong Rust yêu cầu xử lý tất cả các trường hợp có thể (exhaustive matching).

Code Challenge

Complete the for loop using an inclusive range from 1 to 5

Hoàn thành vòng lặp for sử dụng phạm vi bao gồm từ 1 đến 5

for number in 15 {
    println!("{number}");
}
Quiz

Which loop keyword in Rust can return a value through the break statement?

Từ khóa vòng lặp nào trong Rust có thể trả về giá trị qua lệnh break?

True or False

The for loop is the preferred way to iterate over collections in Rust because it is safer and often faster than a while loop with an index.

Vòng lặp for là cách được ưu tiên để duyệt qua các collection trong Rust vì nó an toàn hơn và thường nhanh hơn vòng lặp while với chỉ số.

Chapter Complete!

Great job! Keep the momentum going.

Your progress0 of 19 chapters read
← → to navigate chapters
Built: 4/8/2026, 12:01:11 PM