DEV Community

Cover image for [Rust Guide] 3.5. Control Flow - if else
SomeB1oody
SomeB1oody

Posted on

[Rust Guide] 3.5. Control Flow - if else

3.5.0. Before the Main Content

Welcome to Chapter 3 of Rust self-study. There are 6 sections in total:

  • Variables and Mutability
  • Data Types: Scalar Types
  • Data Types: Compound Types
  • Functions and Comments
  • Control Flow: if else (this article)
  • Control Flow: Loops

Through the small game in Chapter 2 (strongly recommended for beginners who haven't read it), you should already understand the basic syntax of Rust. In Chapter 3, we will go deeper and learn general programming concepts in Rust.

If you like it, remember to like, bookmark, and follow. Follow the series if you want to keep learning.


3.5.1. Basic Understanding of if Expressions

  • The if expression allows executing different code branches based on a condition
    • The condition must be a boolean type. This is different from Ruby, JavaScript, and C++, which automatically convert non-boolean values to boolean
    • The condition can be a literal, an expression, or a variable
  • In an if expression, the code associated with each condition is called a branch
  • Optionally, an else expression can be added afterward
fn main(){
    let machine = 6657;

    if machine < 11451 {
        println!("condition is true");
    } else {
        println!("condition is false");
    }
}
Enter fullscreen mode Exit fullscreen mode

In this example, the value of machine is less than 11451, so the program executes println!("condition is true");. If you change the value of machine so that it is not less than 11451, the program will execute the else branch.


3.5.2. Handling Multiple Conditions with else if

If you need to evaluate multiple conditions without deeply nested else blocks, else if is a good option.

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");
    }
}
Enter fullscreen mode Exit fullscreen mode

Since 6 is divisible by both 3 and 2, both conditions are true. However, if, else if, and else are evaluated from top to bottom, and only the first matching branch is executed.

In this case, else if number % 3 == 0 comes first, so the program prints "Number is divisible by 3", and the later condition is not evaluated.

If there are multiple else if branches, it is often better to refactor using match.

For example, the above code can be rewritten as:

fn main() {
    let number = 6;

    match number {
        n if n % 4 == 0 => println!("Number is divisible by 4"),
        n if n % 3 == 0 => println!("Number is divisible by 3"),
        n if n % 2 == 0 => println!("Number is divisible by 2"),
        _ => println!("Number is not divisible by 4, 3, or 2"),
    }
}
Enter fullscreen mode Exit fullscreen mode

This version using match is more intuitive.


3.5.3. Using if in let Statements

In Rust, if is an expression, so it can be used on the right-hand side of a let statement.

fn main(){
    let condition = true;
    let number = if condition { 5 } else { 6 };
    println!("The value of number is:{}", number);
}
Enter fullscreen mode Exit fullscreen mode

In this example, since condition is true, number is assigned the value 5. The output is:
The value of number is:5

If condition were false, number would be assigned 6 instead.

This syntax is similar to Python, but there are fundamental differences:

  • Rust:

    • if-else is an expression and returns a value
    • It can be used directly inside other expressions
    • Almost all code blocks (including {}) can return values
  • Python:

    • The inline if-else is a ternary expression designed for single-line conditions
    • Standard if-else is a control flow statement and does not return a value
fn main(){
    let condition = true;
    let number = if condition { 5 } else { "6" };
    println!("The value of number is:{}", number);
}
Enter fullscreen mode Exit fullscreen mode

This example will produce a compile-time error:
if and else have incompatible types

Because Rust is a statically typed language, the compiler must determine the type of number at compile time. In this case:

  • The if branch returns an i32
  • The else branch returns a string

Since the types are incompatible, the compiler raises an error.

In short: all branches of an if-else expression must return values of the same type.

Top comments (0)