This is another pattern that is quite common when we interact with Result
types. The pattern goes as follows: when we have a success value, we immediately want to extract it, but when we have an error value, we want to make an early return and propagate the error to the caller. To illustrate this pattern, we will use the following snippet, which uses the usual match expression to act on the Result
type:
// result_common_pattern.rs use std::string::FromUtf8Error; fn str_upper_match(str: Vec<u8>) -> Result<String, FromUtf8Error> { let ret = match String::from_utf8(str) { Ok(str) => str.to_uppercase(), Err(err) => return Err(err) }; println!("Conversion succeeded: {}", ret); Ok(ret) } fn main() { let invalid_str = str_upper_match(vec![197, 198]); println!("{:?}", invalid_str); }
The ?
operator abstracts this pattern, making it possible to write the bytes_to_str
method in a more concise way...