面试题答案
一键面试use std::error::Error;
use std::fs::File;
use std::io::{self, Read};
// 自定义解析错误类型
#[derive(Debug)]
struct ParseError {
message: String,
}
impl std::fmt::Display for ParseError {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
write!(f, "解析错误: {}", self.message)
}
}
impl Error for ParseError {}
// 读取并解析文件的函数
fn read_and_parse_file(file_path: &str) -> Result<String, Box<dyn Error>> {
let mut file = File::open(file_path)?;
let mut contents = String::new();
file.read_to_string(&mut contents)?;
// 这里假设解析逻辑是简单的字符串处理
if contents.contains("invalid") {
Err(Box::new(ParseError {
message: "内容包含无效格式".to_string(),
}))
} else {
Ok(contents)
}
}
fn main() {
match read_and_parse_file("nonexistent_file.txt") {
Ok(result) => {
println!("解析成功: {}", result);
}
Err(err) => {
eprintln!("发生错误: {}", err);
if let Some(source) = err.source() {
eprintln!("错误来源: {}", source);
}
}
}
}
在上述代码中:
- 定义了一个自定义的
ParseError
类型来处理解析格式错误。 read_and_parse_file
函数使用Result
类型来处理文件读取错误(std::io::Error
)和解析错误(ParseError
)。通过?
操作符,错误会自动传播并构建错误链。- 在
main
函数中,通过match
语句优雅地处理不同类型的错误,并通过err.source()
获取错误来源,使错误信息能够清晰地从底层传递到调用层。