Chapter 12

Home

Refactoring: Early Exits and Guard Clauses

Deeply nested if blocks are hard to read. An early exit checks for "bad" cases first and returns immediately, leaving the main logic unindented and clear.

Deep Nesting vs Guard Clauses

Compare these two versions of the same function. Both are correct — but the second one is much easier to follow.

Nested — hard to follow

if (condition_a) {
    if (condition_b) {
        if (condition_c) {
            // actual logic
        }
    }
}

Guard clauses — flat

if (!condition_a) return;
if (!condition_b) return;
if (!condition_c) return;
// actual logic

Problem: Valid Triangle

A triangle is valid if all three sides are positive and the sum of any two sides is greater than the third.

Sample input:
3 4 5

Expected output:
true

C++ — nested

bool is_valid(int a, int b, int c) {
    if (a > 0 && b > 0 && c > 0) {
        if (a + b > c && a + c > b && b + c > a) {
            return true;
        }
    }
    return false;
}

C++ — guard clauses

bool is_valid(int a, int b, int c) {
    if (a <= 0 || b <= 0 || c <= 0) return false;
    if (a + b <= c) return false;
    if (a + c <= b) return false;
    if (b + c <= a) return false;
    return true;
}

Rust — nested

fn is_valid(a: i32, b: i32, c: i32) -> bool {
    if a > 0 && b > 0 && c > 0 {
        if a + b > c && a + c > b && b + c > a {
            return true;
        }
    }
    false
}

Rust — guard clauses

fn is_valid(a: i32, b: i32, c: i32) -> bool {
    if a <= 0 || b <= 0 || c <= 0 { return false; }
    if a + b <= c { return false; }
    if a + c <= b { return false; }
    if b + c <= a { return false; }
    true
}

When to Use Early Exits

Key Takeaways

Practice