乐闻世界logo
搜索文章和话题

How do you define custom ` Error ` types in Rust?

1个答案

1

Defining custom error types in Rust typically involves several steps and leverages specific Rust features. Here is a step-by-step approach to defining a custom error type:

  1. Using enum or struct: Custom errors are typically defined using enum or struct. enum is better suited for representing multiple distinct error types, while struct is appropriate for simpler or single-type errors.

  2. Implementing the std::fmt::Debug and std::fmt::Display traits: This allows errors to be displayed in a developer-friendly manner. Debug is automatically derived, whereas Display typically requires manual implementation.

  3. Implementing the std::error::Error trait: This is essential for making the type an error type. Although not strictly required, doing so ensures compatibility with Rust's error handling ecosystem.

Below is a simple example demonstrating how to define a custom error type:

rust
use std::fmt; // Define an `enum` to represent different error cases #[derive(Debug)] enum MyError { Io(std::io::Error), Parse(std::num::ParseIntError), Other(String), } // Implement `Display` for `MyError`. This is typically used to display error information to users. impl fmt::Display for MyError { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { match self { MyError::Io(err) => write!(f, "IO error: {}", err), MyError::Parse(err) => write!(f, "Parse error: {}", err), MyError::Other(msg) => write!(f, "An error occurred: {}", msg), } } } // Implement `std::error::Error`. // For this simple example, we can directly use the default implementation of `std::error::Error`. impl std::error::Error for MyError {} // Usage example fn main() -> Result<(), MyError> { let result = do_something_that_might_fail()?; println!("Success: {}", result); Ok(()) } fn do_something_that_might_fail() -> Result<i32, MyError> { let input = "not a number"; let num: i32 = input.parse().map_err(MyError::Parse)?; Ok(num) }

In this example, the MyError type defines three possible error cases: an I/O error, a parsing error when converting a string to an integer, and a generic string error message. The implementation of the Display and Error traits ensures this type functions properly within Rust's error handling ecosystem.

When using the ? operator in the do_something_that_might_fail function and encountering an error, it automatically converts std::num::ParseIntError to MyError because we provide a conversion method from ParseIntError to MyError (via map_err).

This approach enables you to handle various error types by using this custom error type to pass error information between your code segments.

2024年6月29日 12:07 回复

你的答案