MST

星途 面试题库

面试题:Rust复杂场景下Result类型与错误链处理

在一个文件读取并解析的场景中,文件可能不存在(`std::io::Error`),解析内容可能格式错误(自定义`ParseError`)。请编写代码,使用Result类型处理这两种错误,并合理构建错误链,使错误信息能够清晰地从底层传递到调用层,同时展示如何在调用层优雅地处理这些不同类型的错误。
45.4万 热度难度
编程语言Rust

知识考点

AI 面试

面试题答案

一键面试
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);
            }
        }
    }
}

在上述代码中:

  1. 定义了一个自定义的ParseError类型来处理解析格式错误。
  2. read_and_parse_file函数使用Result类型来处理文件读取错误(std::io::Error)和解析错误(ParseError)。通过?操作符,错误会自动传播并构建错误链。
  3. main函数中,通过match语句优雅地处理不同类型的错误,并通过err.source()获取错误来源,使错误信息能够清晰地从底层传递到调用层。