Working With Rust Result - Chaining with Map - Part 7
What if we only wanted to parse two numbers and add them together and not return any errors? We can already solve this with and_then
as before:
"10")
parse_number(.and_then(|ten| {
// We have successfully parsed "10" into 10.
"20")
parse_number(.and_then(|twenty| {
// We have successfully parsed "20" into 20.
Ok(ten + twenty)
})
})
We could also just map
over the last function that returns a Result
:
"10")
parse_number(.and_then(|ten| {
// We have successfully parsed "10" into 10.
"20")
parse_number(.map(|twenty| { // We map here
// We have successfully parsed "20" into 20.
+ twenty // We didn't have to wrap the answer in a Result, because we are 'in' a Result
ten })
})
Reminder about map
s definition:
pub fn map<U, F: FnOnce(T) -> U>(self, op: F) -> Result<U, E> {
match self {
Ok(t) => Ok(op(t)),
Err(e) => Err(e),
}
}
map
wraps the result ofop
in anOk
constructor for us so we don’t have to!
In summary:
// pseudocode for map
// Given: Result<T, E>
// Return type: Result<U, E>
: T -> U // Convert success value to a U
op
Ok(t:T) -> op(t) -> U -> Ok(U) // Return converted value in Ok, as a Result<U, E>
Err(e:E) -> Err(e) // Return existing error as Result<U, E>
How do we decide when to use and_then
at the last step of a Result
chain or whether to use map
?
If you need to make a decision about whether to fail or not, then use
and_then
because you can return anOk
to succeed or anErr
to fail. If you simply want to work on theOk
side of a previousResult
, then usemap
.
This logic works only at the last step of a
Result
chain. If you usemap
where you should have usedand_then
, you will end up with a nestedResult
of the sort:Result<Result<T, E>,E>
indicating that you should haveand_then
ed where you had previouslymap
ped.
So many rules to keep in mind! If only there were an easier way to combine Result
s.
- Continue on to Combining Results the Question Mark Operator
- Back to TOC