0Pricing
Learn Rust Coding · Lesson

Match Guards and Bindings

Add conditions and capture values.

Match Guards and Bindings is a free Learn Rust Coding lesson on CoddyKit — lesson 4 of 4. You can read the complete lesson below for free — then practise it hands-on in the browser with a built-in code editor and a 24/7 AI tutor. It is part of the Learn Rust Coding learning path, one of 4 lessons in the course, and your progress syncs across the web and the CoddyKit app.

What Is a Match Guard?

A match guard is an extra if condition added to a match arm. The arm only fires when the pattern matches and the condition is true.

It lets you split one variant into finer cases based on its data.

match number {
    Some(n) if n > 0 => println!("positive"),
    Some(n) => println!("zero or negative"),
    None => println!("no number"),
}

Guard Syntax

Write the pattern, then if condition, then =>. The condition can use any variables the pattern bound.

If the guard is false, Rust moves on to try the next arm.

fn main() {
    let n = 4;
    match n {
        x if x % 2 == 0 => println!("even"),
        _ => println!("odd"),
    }
}

Guards with Enum Data

Guards are most useful with enums that hold data. You bind the inner value, then test it.

Here a positive balance and a negative balance get different messages, even though both are the same variant.

enum Account {
    Balance(i32),
    Closed,
}

fn main() {
    let a = Account::Balance(-5);
    match a {
        Account::Balance(b) if b < 0 => println!("overdrawn"),
        Account::Balance(b) => println!("balance {}", b),
        Account::Closed => println!("closed"),
    }
}

Order Still Matters

Because arms are tried top to bottom, put the more specific guarded arm before the general one.

If the plain Balance(b) arm came first, it would match everything and the guarded arm would never run.

Matching Literal Values

You can also match against specific literals directly in the pattern, without a guard.

Here 0 and 1 are matched exactly, and _ handles the rest.

fn main() {
    let n = 1;
    match n {
        0 => println!("zero"),
        1 => println!("one"),
        _ => println!("many"),
    }
}

Matching Ranges

Patterns can match a range of values with ..=, which is inclusive on both ends.

This is a clean alternative to several comparison guards.

fn main() {
    let score = 85;
    match score {
        0..=59 => println!("fail"),
        60..=100 => println!("pass"),
        _ => println!("out of range"),
    }
}

Binding with the @ Operator

The @ operator lets you test a value against a pattern and bind it to a name at the same time.

Here id @ 1..=5 checks the range and stores the actual value in id so you can print it.

fn main() {
    let n = 3;
    match n {
        id @ 1..=5 => println!("small id {}", id),
        other => println!("other {}", other),
    }
}

Binding the Whole Value

A plain name in a pattern, like other above, binds the entire value. It acts as a catch-all that you can still use.

Use _ when you want to ignore the value, and a name when you need it.

fn main() {
    let n = 99;
    match n {
        0 => println!("zero"),
        value => println!("got {}", value),
    }
}

Guards Plus Bindings Together

You can combine a binding with a guard for precise control: bind the data, then add a condition.

This program flags large even balances specially.

enum Account {
    Balance(i32),
}

fn main() {
    let a = Account::Balance(200);
    match a {
        Account::Balance(b) if b > 100 && b % 2 == 0 => println!("big even {}", b),
        Account::Balance(b) => println!("normal {}", b),
    }
}

Guards Over Multiple Patterns

A guard applies to the whole arm, even when the arm combines patterns with |.

The condition is checked after any of the listed patterns match.

fn main() {
    let n = 6;
    match n {
        2 | 4 | 6 if n > 3 => println!("big even"),
        _ => println!("other"),
    }
}

Putting It Together

This final program combines variants with data, a binding, a guard, and a catch-all to classify a temperature reading.

Change the value and re-run to see different arms trigger.

enum Reading {
    Temp(i32),
    Missing,
}

fn main() {
    let r = Reading::Temp(38);
    match r {
        Reading::Temp(t) if t >= 38 => println!("fever: {}", t),
        Reading::Temp(t) => println!("normal: {}", t),
        Reading::Missing => println!("no reading"),
    }
}

Quick Check

Check your understanding of guards and bindings.

Recap

You learned to refine matches with guards (pattern if condition), match literals and ranges (..=), and create bindings with names or the @ operator.

Combined with everything before, you can now model fixed sets of states, attach data to them, and react to each case precisely. Great work on enums and match!

Frequently asked questions

Is the “Match Guards and Bindings” lesson free?

Yes — the full text of “Match Guards and Bindings” is free to read here on the web, and the Learn Rust Coding course includes 4 lessons in total. To practise it interactively (a built-in code editor and a 24/7 AI tutor) and unlock the rest of the Learn Rust Coding course, upgrade to CoddyKit PRO.

What will I learn in “Match Guards and Bindings”?

Add conditions and capture values. You practise Learn Rust Coding with hands-on code you run directly in the browser, and a 24/7 AI tutor answers your questions as you work through the lesson.

Do I need any experience to start Learn Rust Coding?

No prior experience is required. Learn Rust Coding on CoddyKit is structured for beginners through advanced learners; this is — lesson 4 of 4, so you can start here or from the beginning and move at your own pace.

How long does the “Match Guards and Bindings” lesson take?

Most CoddyKit lessons take about 5–10 minutes. Each one is bite-sized and interactive, so you make steady progress and pick up exactly where you left off across the web and the app.

Can I write and run code in this Learn Rust Coding lesson?

Yes. Every Learn Rust Coding lesson includes a built-in code editor, so you write and run real code right in your browser and get instant AI feedback — no local setup required.

All lessons in this course

  1. Defining Your First Enum
  2. Matching on Enum Variants
  3. Enums with Data
  4. Match Guards and Bindings
← Back to Learn Rust Coding