The Rust question mark (?
) operator is a shorthand that simplifies error handling, particularly when working with functions that return Result
types. It streamlines code by replacing explicit match statements used to unwrap Result
values.
Handling Result
without the ?
Operator
In the absence of the ?
operator, handling a Result
typically involves using a match
statement, as shown the example below:
#[derive(Debug)]
enum MathError {
DivisionByZero,
}
fn div(a: f64, b: f64) -> Result<f64, MathError> {
if b == 0.0 {
Err(MathError::DivisionByZero)
} else {
Ok(a / b)
}
}
fn main() {
let result = div(1.0, 2.0);
match result {
Ok(value) => println!("{}", value),
Err(err) => println!("error: {:?}", err),
}
}
Here, each Result
returned by the div
function must be explicitly unpacked using a match
statement.
Using the ?
Operator
The ?
operator provides a more concise way to handle Result
. If the value of Result
is an Err
, it returns from the function immediately. If it's an Ok
, it unwraps the value for further use.
fn main() -> Result<(), MathError> {
let result = div(1.0, 2.0)?;
println!("{}", result);
Ok(())
}
In this example, div(1.0, 2.0)?
will either:
Immediately return
Err(MathError::DivisionByZero)
ifdiv
returns anErr
, orContinue executing with
result
set to the unwrapped value ofOk(a / b)
.
Notes
Function Signature: The function using
?
must return aResult
(orOption
, in the case of?
used withOption
types).Error Propagation: The
?
operator propagates errors up the call stack, allowing higher-level functions to handle them or report them as needed.Readability: It makes error handling more concise and readable, especially in functions with multiple potential points of failure.
Conclusion
The ?
operator in Rust is a powerful tool that simplifies error handling in functions that return Result
types. It makes code more concise and readable by eliminating the need for repetitive match statements to unwrap Result
values. However, it's important to understand the context in which it can be used and its implications for error propagation in your code.