面试题答案
一键面试1. 错误类型定义
定义AppError
以及各个模块的错误类型。AppError
可以使用enum
来统一包含所有不同类型的错误。
// 模块A的错误类型
#[derive(Debug)]
pub struct ModuleAError;
// 模块B的错误类型
#[derive(Debug)]
pub struct ModuleBError;
// 统一的应用错误类型
#[derive(Debug)]
pub enum AppError {
ModuleAError(ModuleAError),
ModuleBError(ModuleBError),
}
2. 错误转换逻辑
在各个模块中实现从模块特定错误到AppError
的转换。可以通过From
trait 来实现自动转换。
impl From<ModuleAError> for AppError {
fn from(error: ModuleAError) -> Self {
AppError::ModuleAError(error)
}
}
impl From<ModuleBError> for AppError {
fn from(error: ModuleBError) -> Self {
AppError::ModuleBError(error)
}
}
3. 函数间传递和处理
在函数中返回Result
类型,并在调用链中传递AppError
。在需要处理错误的地方,对AppError
进行匹配处理。
// 模块A中的函数,可能返回ModuleAError
fn module_a_function() -> Result<(), ModuleAError> {
// 模拟错误情况
Err(ModuleAError)
}
// 模块B中的函数,可能返回ModuleBError
fn module_b_function() -> Result<(), ModuleBError> {
// 模拟错误情况
Err(ModuleBError)
}
// 组合函数,将模块A和模块B的函数调用并统一处理错误
fn combined_function() -> Result<(), AppError> {
module_a_function()?.map_err(Into::into)?;
module_b_function()?.map_err(Into::into)?;
Ok(())
}
fn main() {
match combined_function() {
Ok(_) => println!("一切正常"),
Err(error) => {
println!("发生错误: {:?}", error);
match error {
AppError::ModuleAError(_) => println!("模块A发生错误"),
AppError::ModuleBError(_) => println!("模块B发生错误"),
}
}
}
}
在上述代码中:
- 首先定义了各个模块的错误类型以及统一的
AppError
类型。 - 通过实现
From
trait,将模块特定错误转换为AppError
。 - 在
combined_function
中调用模块A和模块B的函数,并通过map_err
和Into::into
将模块特定错误转换为AppError
进行传递。 - 在
main
函数中,对combined_function
返回的Result
进行匹配,处理不同类型的AppError
。