The Result enum is a generic type defined in the standard library. It has two variants:
Ok(T): Represents successful execution, containing a value of typeT.Err(E): Represents an error, containing an error value of typeE.
When a function encounters an error condition, it returns a Result with an Err variant. The calling code then handles the error appropriately.
Here's how you can use the Result enum:
-
Define Error Types: Create custom error types to represent different error scenarios specific to your program. These error types can implement the
std::error::Errortrait for consistent error handling. -
Functions Returning
Result: Functions that might encounter errors should declare their return type asResult<T, E>, whereTis the type of the success value andEis the type of the error value. -
Handling Errors with
match: Utilize thematchexpression to analyze the returnedResultvalue. You can handle the success case (Ok) and extract the successful value, or handle the error case (Err) and perform appropriate actions like logging the error or returning an error to the caller. -
Propagating Errors: If a function encounters an error and wants to propagate it to the caller, it simply returns the received
Errvariant. This allows errors to be handled at the appropriate level in your application.
use std::fs;
fn main() {
let greeting_file_result = fs::read_to_string("hello.txt");
match greeting_file_result {
Ok(file_content) => {
println!("File read successfully: {:?}", file_content);
},
Err(error) => {
println!("Failed to read file: {:?}", error);
}
}
}use core::fmt;
use std::{fmt::{Debug, Formatter}, fs};
pub struct FileReadError {
}
fn main() {
let contents = read_file("hello.txt".to_string());
match contents {
Ok(file_content) => {
println!("File content: {}", file_content);
},
Err(error) => {
println!("Error reading file: {:?}", error);
}
}
}
fn read_file(file_path: String) -> Result<String, FileReadError> {
let greeting_file_result = fs::read_to_string("hello.txt");
match greeting_file_result {
Ok(file_content) => {
Ok(file_content)
},
Err(error) => {
let err = FileReadError {};
Err(err)
}
}
}- Clarity: The
Resultenum explicitly conveys success or failure, making code easier to read and understand. - Safety: Encourages explicit error handling, leading to more robust and predictable programs.
- Composability: Allows functions to propagate errors seamlessly, promoting modularity in your codebase.
- Flexibility: The generic nature of
Resultenables returning various success and error types.
- The Rust Programming Language Book: https://doc.rust-lang.org/book/
- Rust by Example: https://doc.rust-lang.org/rust-by-example/