Sling Academy
Home/Rust/Understanding Basic `if` Statements in Rust

Understanding Basic `if` Statements in Rust

Last updated: January 03, 2025

Rust is known for its performance and memory safety features, making it a popular choice among systems programmers and developers working on high-performance applications. Understanding control flow is crucial when programming in any language, and one of the fundamental control flow tools you’ll encounter is the if statement. In Rust, if statements work similarly to other languages, but there are some unique characteristics that make it essential to understand how they function within the Rust ecosystem.

The Basic if Statement

An if statement allows you to execute certain parts of code based on a condition. If the condition evaluates to true, the block of code within the if statement runs; otherwise, it doesn’t. Here’s a simple example of an if statement in Rust:

fn main() {
    let number = 5;

    if number < 10 {
        println!("The number is less than 10");
    }
}

In this code, the condition number < 10 evaluates to true. Therefore, the message "The number is less than 10" gets printed to the console. If the condition were false, nothing would happen.

Using else with if

Typically, you'd want your code to do something different if the condition is false. This can be achieved using the else keyword:

fn main() {
    let number = 15;

    if number < 10 {
        println!("The number is less than 10");
    } else {
        println!("The number is 10 or greater");
    }
}

In this case, because number is 15, the condition is false, and the else block runs, printing "The number is 10 or greater".

Combining if and else if

When you have multiple conditions to check, you can combine if with else if. This allows your program to check multiple conditions sequentially:

fn main() {
    let number = 25;

    if number < 10 {
        println!("The number is less than 10");
    } else if number < 20 {
        println!("The number is between 10 and 19");
    } else {
        println!("The number is 20 or greater");
    }
}

Here, the Rust compiler checks each condition in turn and runs the block of the first matching condition. Since number is 25, the last condition evaluate to true.

Using if Statements in let Bindings

Rust allows you to use if in let statements to conditionally assign values. This can be particularly useful for concise code:

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

In this example, number will be assigned a value of 5 because condition is true. If condition were false, number would then be 10.

Note that both the if and else branches must evaluate to values of the same type; otherwise, you’ll encounter a compilation error.

Nesting if Statements

if statements can also be nested for more complex decision-making processes:

fn main() {
    let n = 6;

    if n % 2 == 0 {
        if n % 3 == 0 {
            println!("The number is divisible by 2 and 3");
        } else {
            println!("The number is divisible by 2 but not by 3");
        }
    } else {
        println!("The number is not divisible by 2");
    }
}

In this code, the Rust compiler first evaluates if n is divisible by 2. If true, it checks if n is divisible by 3. Depending on those conditions, different messages get printed.

Conclusion

Rust's if statements may come across as familiar to developers with experience in other programming languages. However, its integration within Rust’s unique expression-oriented syntax requires attention. Understanding its use cases and behavior can result in a more efficient and readable Rust codebase. Today, we've seen how you can use if, else if, and else blocks to construct versatile control flows.

Next Article: Exploring `if`-`else if`-`else` Chains for Conditional Logic in Rust

Series: Control Flow in Rust

Rust

You May Also Like

  • E0557 in Rust: Feature Has Been Removed or Is Unavailable in the Stable Channel
  • Network Protocol Handling Concurrency in Rust with async/await
  • Using the anyhow and thiserror Crates for Better Rust Error Tests
  • Rust - Investigating partial moves when pattern matching on vector or HashMap elements
  • Rust - Handling nested or hierarchical HashMaps for complex data relationships
  • Rust - Combining multiple HashMaps by merging keys and values
  • Composing Functionality in Rust Through Multiple Trait Bounds
  • E0437 in Rust: Unexpected `#` in macro invocation or attribute
  • Integrating I/O and Networking in Rust’s Async Concurrency
  • E0178 in Rust: Conflicting implementations of the same trait for a type
  • Utilizing a Reactor Pattern in Rust for Event-Driven Architectures
  • Parallelizing CPU-Intensive Work with Rust’s rayon Crate
  • Managing WebSocket Connections in Rust for Real-Time Apps
  • Downloading Files in Rust via HTTP for CLI Tools
  • Mocking Network Calls in Rust Tests with the surf or reqwest Crates
  • Rust - Designing advanced concurrency abstractions using generic channels or locks
  • Managing code expansion in debug builds with heavy usage of generics in Rust
  • Implementing parse-from-string logic for generic numeric types in Rust
  • Rust.- Refining trait bounds at implementation time for more specialized behavior