Result
-
Result<T, E>is the type used for returning and propagating errors. -
It is an enum with the variants,
Ok(T), representing success and containing a value, andErr(E), representing error and containing an error value.
enum Result<T, E> {
Ok(T),
Err(E),
}
#[derive(Debug)]
enum Version { Version1, Version2 }
fn parse_version(header: &[u8]) -> Result<Version, &'static str> {
match header.get(0) {
None => Err("invalid header length"),
Some(&1) => Ok(Version::Version1),
Some(&2) => Ok(Version::Version2),
Some(_) => Err("invalid version"),
}
}
let version = parse_version(&[1, 2, 3, 4]);
match version {
Ok(v) => println!("working with version: {v:?}"),
Err(e) => println!("error parsing header: {e:?}"),
}
The
?
operator
-
The operator is defined to perform an early return of a value out of the function
-
The
?operator can only be used in functions whose return type is compatible with the value the?is used on.-
Weβre only allowed to use the
?operator in a function that returnsResult,Option, or another type that implementsFromResidual. -
By default, use
Result.
-
-
Usage :
use std::fs::File; use std::io::{self, Read}; fn read_username_from_file() -> Result<String, io::Error> { let mut username_file = File::open("hello.txt")?; let mut username = String::new(); username_file.read_to_string(&mut username)?; Ok(username) }use std::fs::File; use std::io::{self, Read}; fn read_username_from_file() -> Result<String, io::Error> { let mut username = String::new(); File::open("hello.txt")?.read_to_string(&mut username)?; Ok(username) } -
Ex1 :
-
Without
?:use std::fs::File; use std::io::prelude::*; use std::io; struct Info { name: String, age: i32, rating: i32, } fn write_info(info: &Info) -> io::Result<()> { // Early return on error let mut file = match File::create("my_best_friends.txt") { Err(e) => return Err(e), Ok(f) => f, }; if let Err(e) = file.write_all(format!("name: {}\n", info.name).as_bytes()) { return Err(e) } if let Err(e) = file.write_all(format!("age: {}\n", info.age).as_bytes()) { return Err(e) } if let Err(e) = file.write_all(format!("rating: {}\n", info.rating).as_bytes()) { return Err(e) } Ok(()) } -
With
?:use std::fs::File; use std::io::prelude::*; use std::io; struct Info { name: String, age: i32, rating: i32, } fn write_info(info: &Info) -> io::Result<()> { let mut file = File::create("my_best_friends.txt")?; // Early return on error file.write_all(format!("name: {}\n", info.name).as_bytes())?; file.write_all(format!("age: {}\n", info.age).as_bytes())?; file.write_all(format!("rating: {}\n", info.rating).as_bytes())?; Ok(()) }
-
Unwrapping
-
These methods extract the contained value in a
Result<T, E>when it is theOkvariant. -
-
expectpanics with a provided custom message. -
unwrappanics with a generic message. -
unwrap_orreturns the provided default value. -
unwrap_or_defaultreturns the default value of the typeT(which must implement theDefaulttrait). -
unwrap_or_elsereturns the result of evaluating the provided function.
-
-
The panicking methods
expectandunwraprequireEto implement theDebugtrait. -
These methods extract the contained value in a
Result<T, E>when it is theErrvariant. -
They require
Tto implement theDebugtrait. -
-
expect_errpanics with a provided custom message. -
unwrap_errpanics with a generic message.
-