Start learning free

LESSON 86 OF 414 · CONDITIONAL STATEMENTS

Chaining Conditionals in Rust: else if

Lesson Read the full explanation

Sometimes we can have more than two possible scenarios which need a different code to be ran. We can add else if statements to allow for as many outcomes as we want:

let language = "Python";
if language == "JavaScript" {
    println!("It's super popular!");
} else if language == "Python" {
    println!("It's so simple!");
} else if language == "Java" {
    println!("It's pretty hardcore!");
} else {
    println!("It's exotic!");
}

In the example above, language == "JavaScript" evaluates to false, so we move on and enter the following else if.

There, language == "Python" evaluates to true, so we execute what's inside that block and print "It's so simple!".

The rest of the conditions are not evaluated.

In case none of the conditions evaluates to true, then the code in the final else statement would execute. For example, if language was "Go", the program would have printed "It's exotic!"


Assignment
Follow the Coding Tutorial and let's write some chained conditionals.


Hint
Look at the examples above if you get stuck.


STEP 1 OF 4
    Ctrl + Enter to check

    RUST · CONDITIONAL STATEMENTS

    Chaining Conditionals in Rust, explained

    More than two outcomes

    An if/else chooses between two paths. When there are three or more cases, add else if branches between the if and the final else. Rust checks the conditions from top to bottom and runs the block of the first one that is true. After that, the rest of the chain is skipped, and no later condition is evaluated.

    let language = "Python";
    if language == "JavaScript" {
        println!("It's super popular!");
    } else if language == "Python" {
        println!("It's so simple!");
    } else if language == "Java" {
        println!("It's pretty hardcore!");
    } else {
        println!("It's exotic!");
    }
    

    With language set to "Python", the first condition is false, so the chain moves on. The second is true, so the program prints It's so simple! and ignores the "Java" check. If language were "Go", every condition would be false and the final else would print It's exotic!.

    The rules of a chain

    • At most one block runs. With a final else, exactly one block runs. Without it, none runs if every condition is false.
    • Order matters. A later branch runs only when every earlier condition was false, so each else if can rely on what the earlier ones ruled out. This is what lets you write short conditions.
    • The else has no condition and must come last. It catches everything the branches above did not.
    • Syntax. Rust conditions have no parentheses, the braces are required, and each condition must be a bool. Write else if as two words, not elif or elseif.

    Order and ranges

    Ranges are where the ordering helps most. Look at this chain on a number:

    if grade < 5 {
        println!("low");
    } else if grade <= 7 {
        println!("middle");
    } else {
        println!("high");
    }
    

    The second condition is only grade <= 7, not grade >= 5 && grade <= 7, because the first branch has already caught everything below 5. Written the other way round, the chain would be wrong: if you put grade <= 7 first, a grade of 3 would match it and print "middle". Always start with the most restrictive case, or reason about what each branch has already excluded.

    An if chain is an expression

    In Rust an if chain can produce a value. Write the value of each branch without a semicolon and every branch must have the same type:

    let word = if grade < 5 { "low" } else if grade < 9 { "mid" } else { "high" };
    

    Here word is "mid" when grade is 8. In this form the final else is required, because the expression needs a value on every path. If the branches have different types, such as "low" and 3, the compiler reports that the if and else have incompatible types. When you are matching one value against many patterns, a match is often tidier than a long chain, and the next lesson covers it.

    Common mistakes

    • Using separate ifs instead of else if. Separate if statements are all checked, so more than one block can run.
    • Wrong order. Broad conditions placed first hide the narrower ones below them.
    • Off-by-one at the boundaries. < and <= differ exactly at the border value. Decide which side each boundary value belongs to.
    • Using = instead of ==. A condition with a single = does not compile.

    The lesson's exercise

    The starter code defines let grade = 8;. The task is to print a message for each grade band.

    1. Start the chain with if grade < 5 and print "Failed the test". Failing grades are handled first.
    2. Add else if grade <= 7 to print "Passed the test". Grades 5, 6 and 7 reach this branch, because lower grades were handled above.
    3. Add else if grade <= 9 to print "Good Job", which covers 8 and 9.
    4. Finish with an else that prints "Perfect" for any grade above 9.
    let grade = 8;
    if grade < 5 {
        println!("Failed the test");
    } else if grade <= 7 {
        println!("Passed the test");
    } else if grade <= 9 {
        println!("Good Job");
    } else {
        println!("Perfect");
    }
    

    For grade = 8, the first two conditions are false and the third is true, so the program prints Good Job. The other grades give: 3 prints Failed the test, 5 and 7 print Passed the test, 9 prints Good Job and 10 prints Perfect.

    Key takeaways

    • else if adds as many cases as you need; the first true condition wins.
    • Later branches only run when all earlier conditions were false, so order the checks deliberately.
    • The final else takes no condition and catches the rest.
    • An if chain can be an expression, and then every branch must have the same type and the else is required.
    Keep going with RustAbout 340 step-by-step lessons, from your first line of code to coding interviews. Free to start.
    Start learning free