use std::fmt;
use std::error::Error;
// 假设自定义错误类型
#[derive(Debug)]
struct CustomError {
msg: String,
}
impl fmt::Display for CustomError {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(f, "{}", self.msg)
}
}
impl Error for CustomError {}
// 假设这是func1函数
fn func1() -> Result<(), Box<dyn Error>> {
// 模拟成功
Ok(())
}
// 假设这是func2函数
fn func2() -> Result<(), Box<dyn Error>> {
// 模拟失败
Err("Some error".into())
}
// 假设这是func3函数
fn func3() -> Result<(), Box<dyn Error>> {
// 模拟成功
Ok(())
}
fn main_function() -> Result<(), Box<dyn Error>> {
func1()?;
match func2() {
Ok(()) => (),
Err(e) => {
if e.to_string().contains("specific_error_type_1") {
// 记录日志,这里简单打印
println!("Logging error: {}", e);
} else if e.to_string().contains("specific_error_type_2") {
return Err(CustomError {
msg: "Custom error from func2".to_string(),
}.into());
} else {
return Err(e);
}
}
}
func3()?;
Ok(())
}
实现思路
- 依次调用函数:使用
?
运算符可以简洁地处理前一个函数返回的错误,如果函数返回Err
,则直接将错误返回给调用者。首先调用func1
,使用?
运算符,如果func1
返回错误,函数main_function
就会返回这个错误。
func2
错误处理:func2
调用后,不能直接使用?
运算符,因为需要根据不同错误类型做不同处理。所以使用match
表达式对func2
的返回值进行匹配。如果是Ok
,则继续执行后续代码;如果是Err
,则检查错误类型。如果是特定的错误类型1,记录日志;如果是特定的错误类型2,返回自定义错误;其他错误类型则直接返回。
- 继续调用
func3
:在处理完func2
的错误后,如果没有返回错误,继续调用func3
,并使用?
运算符处理其可能返回的错误。如果func3
返回错误,函数main_function
也会返回这个错误。如果所有函数都成功调用,main_function
返回Ok(())
。