let else
Statements
For the common case of matching a pattern and returning from the function, use
let else
.
The “else” case must diverge (return
, break
, or panic - anything but falling
off the end of the block).
fn hex_or_die_trying(maybe_string: Option<String>) -> Result<u32, String> { let s = if let Some(s) = maybe_string { s } else { return Err(String::from("got None")); }; let first_byte_char = if let Some(first) = s.chars().next() { first } else { return Err(String::from("got empty string")); }; let digit = if let Some(digit) = first_byte_char.to_digit(16) { digit } else { return Err(String::from("not a hex digit")); }; Ok(digit) } fn main() { println!("result: {:?}", hex_or_die_trying(Some(String::from("foo")))); }
The rewritten version is:
#![allow(unused)] fn main() { fn hex_or_die_trying(maybe_string: Option<String>) -> Result<u32, String> { let Some(s) = maybe_string else { return Err(String::from("got None")); }; let Some(first_byte_char) = s.chars().next() else { return Err(String::from("got empty string")); }; let Some(digit) = first_byte_char.to_digit(16) else { return Err(String::from("not a hex digit")); }; Ok(digit) } }
More to Explore
- This early return-based control flow is common in Rust error handling code,
where you try to get a value out of a
Result
, returning an error if theResult
wasErr
. - If students ask, you can also demonstrate how real error handling code would
be written with
?
.