Start learning free

LESSON 78 OF 414 · CONDITIONAL STATEMENTS

Redundant Else Statement in Rust

Lesson Read the full explanation

We will learn a simple trick to improve our code quality: removing redundant else statements.

Video Lesson:

STEP 1 OF 1
    Ctrl + Enter to check

    RUST · CONDITIONAL STATEMENTS

    Redundant Else Statement in Rust, explained

    What a redundant else is

    An else is redundant when the if branch before it always ends the function with return. Once that return runs, nothing after it in the function executes. The code that follows the if block can only be reached when the condition was false, which is exactly what the else was saying. Wrapping it in else { ... } adds braces and a level of indentation without changing what the function does.

    The function in this lesson is negative. It returns n when n is negative and -n otherwise, so the result is never positive:

    impl Solution {
        fn negative(n: i32) -> i32 {
            if n < 0 {
                return n;
            } else {
                return -n;
            }
        }
    }
    

    It is correct, but both branches return, so the else does no work.

    Removing it

    Delete the else { and its closing brace, and move the second return out of the block. The if keeps its own closing }:

    impl Solution {
        fn negative(n: i32) -> i32 {
            if n < 0 {
                return n;
            }
            return -n;
        }
    }
    

    The behaviour is identical. With n = 5 the condition is false, the if block is skipped and the function returns -5. With n = -3 the if block returns -3 straight away, and the last line never runs. With n = 0 the result is 0. The two versions give the same answers for all three inputs.

    Why it reads better

    • The code is flatter. The main path of the function sits at the same indentation as the checks, instead of being pushed into a block.
    • The reader sees a guard: "if this case holds, return now." Everything below is the general case.
    • The effect grows with the code. A function with several early returns and a nested else after each one soon becomes a staircase of braces. Without the else blocks it stays a straight list of checks.

    The same idea in Rust's own style

    In Rust, if is an expression, and the last expression of a function body, written without a semicolon, is its return value. Because of that, the original function can also be written without any return:

    fn negative(n: i32) -> i32 {
        if n < 0 { n } else { -n }
    }
    

    Here the else is not redundant, because it is needed to give the expression a value on both paths. It gives the same results as the version above: 5 becomes -5 and -3 stays -3. The lesson's exercise uses explicit return statements, and with return the else can go.

    When the else is not redundant

    The trick only works when the if branch really leaves the function. If it falls through to the end of its block, the code after the if runs in both cases, and removing the else changes the behaviour:

    fn describe(n: i32) {
        if n < 0 {
            println!("negative");
        } else {
            println!("not negative");
        }
    }
    

    Here the two branches only print, and nothing returns. Take away the else and the second println! would run for every input, including negative ones. Before you remove an else, check that the branch above it always ends with return (or something else that leaves the function, such as break or continue inside a loop).

    The lesson's exercise

    1. Read the function and find the branch that ends with return n;. Everything after it runs only when n < 0 is false.
    2. Delete the else keyword and its opening brace.
    3. Delete the matching closing brace, so the if block ends right after return n;.
    4. Keep return -n; as the next line, now at the function's top level, and un-indent it one level.

    The tests check only what the function returns, so the cleaned-up version passes exactly like the original.

    Key takeaways

    • If an if branch always returns, the else after it is redundant.
    • Removing it keeps the behaviour and cuts nesting and braces.
    • Do not remove an else when the if branch can fall through, because both branches would then run the code that follows.
    • In Rust, an if/else used as the function's final expression, with no return, is another clean form, and there 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