On the function below, we have a function that returns a bool
wrapped by a Result
.
We want to use the bool that is inside of this function, but we don't want to use things like a if let, for example.
How could we do this?
We can't do it, because we can't apply an unary operator to a Result<bool>
- we have to first unwrap the bool inside the Result
.
However, there's a lean solution to it: the question mark operator.
We want to evaluate the return of self.user_intention()
. That's what we do when we use the !
combined with the if
keyword. It's a shortcut for evaluating a bool variable assigned to the return of this function.
However, as this function can return an Err
- since its type is a Result<bool, TerminalError>
- we have to deal with the failing case as well.
We want to do so by using a bubble up, which is: propagate the error to a higher level by returning it.
Then, we have two cases: the success case, in which we evaluate the value inside of the Ok variant, and the failure case, in which we return the error.
There's a very important detail here: returning vs evaluating. Let's look it in detail. When a match returns the same type on all branches, it works as an expression; for example:
let num_name = match num {
0 => "zero",
1 => "um",
2 => "dois",
_ => "outro",
};
But what happens if one of the branches uses the keyword return
?
Basically, the returned value won't be assigned to the variable num_name
. It happens because the return
keyword "stops" the flow once it is executed. So, we will return from the function - and here it is our opportunity to apply the bubble up!
The behavior described above can be written as a match
, as it follows: