← Back to Rust Course | Chapter 8: Enums & Pattern Matching | Lesson 4 of 7

if let Syntax

if let is a shortcut for handling just one interesting case of a value, without writing out every possibility.
Syntax
rust
if let Pattern(binding) = value {
    // body
} else {
    // no match
}

Basic if let

if let matches a value against a single pattern and runs its block only if that pattern matches, skipping the block entirely otherwise. It's a shorthand for a match that only cares about one case.

Example: Basic if let

markup
// Entry point: execution of the program starts here
fn main() {
    // Declare an immutable variable `config_max` (a `Option<u8>`), set to `Some(3)`
    let config_max: Option<u8> = Some(3);
    // If `config_max` matches `Some(max)`, bind and run this block
    if let Some(max) = config_max {
        // Print "Maximum is configured to be {}" to the console, substituting in `max` (with a trailing newline)
        println!("Maximum is configured to be {}", max);
    }
}

if let With else

Adding an else block to if let lets you handle the non-matching case as well, giving you full coverage with less boilerplate than a match when there is only one interesting variant.

Example: if let With else

markup
// Entry point: execution of the program starts here
fn main() {
    // Declare an immutable variable `value` (a `Option<i32>`), set to `None`
    let value: Option<i32> = None;
    // If `value` matches `Some(v)`, bind and run this block
    if let Some(v) = value {
        // Print "Got value: {}" to the console, substituting in `v` (with a trailing newline)
        println!("Got value: {}", v);
    // Otherwise, run this branch
    } else {
        // Print "No value present" to the console (with a trailing newline)
        println!("No value present");
    }
}

if let With an Enum

if let works with any enum, not just Option, letting you handle a single variant of interest concisely while ignoring the rest.

Example: if let With an Enum

markup
// Define an enum `Shape` listing its possible variants
enum Shape {
    Circle(f64),
    Square(f64),
}

// Entry point: execution of the program starts here
fn main() {
    // Declare an immutable variable `shape`, set to `Shape::Circle(3.0)`
    let shape = Shape::Circle(3.0);
    // If `shape` matches `Shape::Circle(radius)`, bind and run this block
    if let Shape::Circle(radius) = shape {
        // Print "Circle with radius {}" to the console, substituting in `radius` (with a trailing newline)
        println!("Circle with radius {}", radius);
    }
}

Choosing if let vs match

if let is best when you only care about one specific pattern and want to ignore everything else concisely; match is better when you need to handle every possible case explicitly.

Example: Choosing if let vs match

markup
// Entry point: execution of the program starts here
fn main() {
    // Declare an immutable variable `items`, set to `[Some(1), None, Some(3)]`
    let items = [Some(1), None, Some(3)];
    // Loop over `items.iter()`, binding each item to `item`
    for item in items.iter() {
        // If `item` matches `Some(n)`, bind and run this block
        if let Some(n) = item {
            // Print "Found: {}" to the console, substituting in `n` (with a trailing newline)
            println!("Found: {}", n);
        }
    }
}
Related Topics
{# common_mistakes/chapter_summary/browser_support: on Hindi pages the view already swaps in the hi_ translation fields (or blanks these out if untranslated), so this renders correctly for both languages without a lang_code check here. #}
Common Mistakes
  1. Using a full match with a wildcard _ => {} arm when a much shorter if let would express the same logic.
  2. Forgetting if let is non-exhaustive by design -- it deliberately ignores every case that doesn't match the given pattern.
  3. Not realizing if let ... else can handle the non-matching case too, combining the concise syntax with full coverage.
Chapter Summary
  • if let pattern = value { ... } runs the block only when value matches the given pattern.
  • if let is useful when only one variant of a match actually matters, avoiding boilerplate for the rest.
  • An else branch can be attached to if let to handle every other case in one place.
  • Unlike match, if let does not need to be exhaustive.
🔒

Chapter Quiz — Complete all 7 topics to unlock

0/7 topics done

Complete these topics first:

Login to run this code

C/C++/Java/PHP execution requires a free account. Your code is saved — you'll land right back in the editor after logging in.