rust / intermediate
Snippet
The ? Operator: Elegant Error Propagation
The ? operator is syntactic sugar for error propagation that makes code concise and readable. Instead of manually matching on Result variants and returning errors, ? automatically unwraps Ok values and returns Err values early from the current function. Combined with the From trait, ? can even convert between error types automatically—ParseIntError automatically converts to MathError because we implemented From.
snippet.rs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
use std::num::ParseIntError;use std::fmt;#[derive(Debug)]enum MathError {DivisionByZero,NegativeLogarithm,ParseError(ParseIntError),}impl fmt::Display for MathError {fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {match *self {MathError::DivisionByZero => write!(f, "Division by zero"),MathError::NegativeLogarithm => write!(f, "Logarithm of negative number"),MathError::ParseError(ref e) => write!(f, "Parse error: {}", e),}}}impl From<ParseIntError> for MathError {fn from(err: ParseIntError) -> Self {MathError::ParseError(err)}}fn parse_and_divide(a: &str, b: &str) -> Result<f64, MathError> {let a_num: i32 = a.parse()?;let b_num: i32 = b.parse()?;if b_num == 0 { return Err(MathError::DivisionByZero); }Ok(a_num as f64 / b_num as f64)}fn main() {let result = parse_and_divide("10", "2");println!("Result: {:?}", result);}
Breakdown
1
impl From<ParseIntError> for MathError {
Enables automatic error type conversion when using ?
2
let a_num: i32 = a.parse()?;
parse() returns Result; ? unwraps Ok or returns Err early
3
if b_num == 0 { return Err(MathError::DivisionByZero); }
Explicit error return for domain-specific validation
4
Ok(a_num as f64 / b_num as f64)
Ok wrapper indicates successful computation