MST

星途 面试题库

面试题:Rust中结构体与Result枚举结合处理错误的基础应用

假设你正在编写一个Rust程序,用于读取一个文件的内容并将其解析为整数。如果文件不存在或者内容无法解析为整数,你需要恰当地处理这些错误。请使用结构体和Result枚举来实现这个功能,并给出关键代码示例。
22.7万 热度难度
编程语言Rust

知识考点

AI 面试

面试题答案

一键面试
use std::fs::File;
use std::io::{self, Read};
use std::num::ParseIntError;

// 定义一个结构体来包装文件读取和解析错误
struct FileReadError {
    source: io::Error,
}

impl std::fmt::Debug for FileReadError {
    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
        write!(f, "FileReadError: {}", self.source)
    }
}

impl std::fmt::Display for FileReadError {
    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
        write!(f, "FileReadError: {}", self.source)
    }
}

impl std::error::Error for FileReadError {
    fn source(&self) -> Option<&(dyn std::error::Error + 'static)> {
        Some(&self.source)
    }
}

// 定义从io::Error转换为FileReadError的From实现
impl From<io::Error> for FileReadError {
    fn from(error: io::Error) -> Self {
        FileReadError { source: error }
    }
}

// 定义解析整数错误包装结构体
struct ParseError {
    source: ParseIntError,
}

impl std::fmt::Debug for ParseError {
    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
        write!(f, "ParseError: {}", self.source)
    }
}

impl std::fmt::Display for ParseError {
    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
        write!(f, "ParseError: {}", self.source)
    }
}

impl std::error::Error for ParseError {
    fn source(&self) -> Option<&(dyn std::error::Error + 'static)> {
        Some(&self.source)
    }
}

// 定义从ParseIntError转换为ParseError的From实现
impl From<ParseIntError> for ParseError {
    fn from(error: ParseIntError) -> Self {
        ParseError { source: error }
    }
}

// 定义一个函数来读取文件并解析为整数
fn read_file_and_parse_to_int(file_path: &str) -> Result<i32, Box<dyn std::error::Error>> {
    let mut file = File::open(file_path)?;
    let mut contents = String::new();
    file.read_to_string(&mut contents)?;
    let number = contents.trim().parse()?;
    Ok(number)
}

fn main() {
    match read_file_and_parse_to_int("example.txt") {
        Ok(number) => println!("Parsed number: {}", number),
        Err(e) => eprintln!("Error: {}", e),
    }
}
  1. 错误结构体定义
    • FileReadError 结构体用于包装文件读取相关的 io::Error
    • ParseError 结构体用于包装整数解析相关的 ParseIntError
    • 为这两个结构体实现了 DebugDisplayError 特征,方便错误处理和展示。
    • 实现了从 io::ErrorFileReadError 和从 ParseIntErrorParseErrorFrom 特征,以便在 ? 操作符中自动转换。
  2. 核心函数 read_file_and_parse_to_int
    • 使用 File::open 尝试打开文件,如果文件不存在或其他I/O错误,? 操作符会返回 Err
    • 使用 read_to_string 读取文件内容到 String
    • 使用 trim 去除字符串两端的空白字符,然后调用 parse 尝试解析为 i32。如果解析失败,? 操作符也会返回 Err
  3. main 函数
    • 调用 read_file_and_parse_to_int 函数,并通过 match 语句处理 Result 枚举的 OkErr 情况。Ok 时打印解析后的整数,Err 时打印错误信息。