https://stackoverflow.com/questions/42917566/what-is-this-question-mark-operator-about
As you may have noticed, Rust does not have exceptions. It has panics, but their use for error-handling is discouraged (they are meant for unrecoverable errors).
In Rust, error handling uses Result. A typical example would be:
fn halves_if_even(i: i32) -> Result<i32, Error> { if i % 2 == 0 { Ok(i / 2) } else { Err(/* something */) } } fn do_the_thing(i: i32) -> Result<i32, Error> { let i = match halves_if_even(i) { Ok(i) => i, Err(e) => return Err(e), }; // use `i` }
This is great because:
- when writing the code you cannot accidentally forget to deal with the error,
- when reading the code you can immediately see that there is a potential for error right here.
It's less than ideal, however, in that it is very verbose. This is where the question mark operator
?
comes in.The above can be rewritten as:
fn do_the_thing(i: i32) -> Result<i32, Error> { let i = halves_if_even(i)?; // use `i` }
which is much more concise.
What
?
does here is equivalent to thematch
statement above with an addition. In short:
- It unpacks the
Result
if OK- It returns the error if not, calling
From::from
on the error value to potentially convert it to another type.It's a bit magic, but error handling needs some magic to cut down the boilerplate, and unlike exceptions it is immediately visible which function calls may or may not error out: those that are adorned with
?
.