Skip to content

Rust If Let and While Let

You’ve used match to handle Option and Result. Most of the time, though, you only actually care about one pattern and want to ignore everything else. Writing a full match with a _ => {} arm just to do nothing works, but it’s more ceremony than the situation needs. if let is the shortcut.

fn main() {
let age: Option<i32> = Some(30);
match age {
Some(value) => println!("Age is {value}"),
_ => {}, // we don't actually care about this case
}
}

That _ => {} is doing nothing except satisfying match’s “every case must be handled” rule. If all you want is to act on Some, this is more code than the idea deserves.

fn main() {
let age: Option<i32> = Some(30);
if let Some(value) = age {
println!("Age is {value}");
}
}

Output:

Age is 30
▶ Try it Yourself

Read it as: “if age matches the pattern Some(value), run this block, with value bound to what was inside.” If age is None, the block is simply skipped — no error, nothing printed.

if let can have an else, just like a regular if:

fn main() {
let age: Option<i32> = None;
if let Some(value) = age {
println!("Age is {value}");
} else {
println!("No age given");
}
}
▶ Try it Yourself

Works the same way with Result, which you met on the Result page:

fn main() {
let input = "42";
if let Ok(number) = input.parse::<i32>() {
println!("Parsed: {number}");
} else {
println!("Couldn't parse that");
}
}
▶ Try it Yourself

while let applies the same idea to a loop: keep looping as long as a value matches a pattern. It’s especially handy for draining a collection:

fn main() {
let mut stack = vec![1, 2, 3];
while let Some(top) = stack.pop() {
println!("{top}");
}
}

Output:

3
2
1
▶ Try it Yourself

.pop() returns Some(value) while there’s something left, and None once the vector is empty — at which point while let stops the loop automatically. No manual length check needed.

Use match when you genuinely need to handle multiple cases differently. Reach for if let when there’s really only one pattern you care about and everything else should just be ignored. It’s not a replacement for match — just a shorter way to write the common “I only care about one arm” case.

  • if let Pattern = value { ... } runs the block only if value matches Pattern — everything else is silently skipped.
  • Add else to handle the non-matching case, same as a regular if.
  • while let Pattern = value { ... } loops as long as the value keeps matching, useful for draining a collection with .pop().
  • Use if let/while let when you only care about one pattern; use match when you need to handle several distinctly.

Quick check

1. What happens when if let Some(value) = age runs and age is None?

2. When should you reach for match instead of if let?

3. In while let Some(top) = stack.pop() { ... }, when does the loop stop?

Score: 0 / 3