Reputation: 5462
I am trying to learn Rust and I would like to understand the conceptual fundamentals. In Rust, we often use Result<T, E>
as a return type. Basically, a type, which consists of - Ok()
and Err()
, and it is up to the caller to handle these.
But what I am kind a surprised is fact, that both Ok()
and Err()
, have again their "options" -> Namely Some
and None
.
fn integer_divide(a: u32, b: u32) -> Result<u32, String> {
if b != 0 {
Ok(a / b)
} else {
Err("Division by zero!".into())
}
}
let result = integer_divide(5, 0);
if(result.is_err()){
if(result.err().is_some()){
// some logic
}
}
So basically, we need to double check before we get to resulting value of every function (First for Err
or Ok
, then for Some
or None
)? If yes, I find this very clunky. Especially in case my integer_divide
function, where reliably I am able to say, it can never have a result with Err()
of None
value.
It would make more sense to me, if we would just unwrap Err()
, then check if it's value is None
or some other type... Especially in case, where I am 100% sure, it cannot hold None
value. Any thoughts appreciated.
I am aware of existence of ?
operator. I just want to understand concept.
Upvotes: 3
Views: 4719
Reputation: 154856
is_err()
serves to answer the question "does this result contain an error?". If that's all you're interested in, then you're good to go:
if result.is_err() {
// logic here
}
Result
is just an enum with two well-defined variants, so if you also need to access the value of the error, you can use if let
to match the Err
variant:
if let Err(e) = result {
// logic here, `e` contains the error value
}
Finally, if you need to handle both Ok
and Err
in the same go, use match
, as shown in the answer by @prog-fh.
Upvotes: 2
Reputation: 16785
Considering result.err()
alone, nothing ensures that result
actually contains an error, thus this method cannot return an error every time we invoke it.
The usual way in Rust to provide something which is optional is to return an Option
, hence the is_some()
method.
This does not mean that the Result
contains such an Option
; this Option
is created by the err()
method just in case result
did not contain an error.
You know that there is actually an error inside result
because you tested just before with result.is_err()
; but the designer of the err()
method did not know, a long time ago, that you would test is_err()
just before calling err()
.
The usual way to handle result
without double check would be
match result {
Ok(v) => {
println!("result is {}", v);
}
Err(e) => {
println!("error: {}", e);
}
}
Upvotes: 6