MST

星途 面试题库

面试题:Rust结构体与Option枚举在异步编程及错误处理中的深度交互

在一个异步Rust项目中,定义一个结构体`DatabaseRecord`,包含`id`(唯一标识,整数类型)、`data`(任意复杂的数据结构,自定义)字段。通过异步函数从数据库中获取记录,返回值类型为`Result<Option<DatabaseRecord>, DatabaseError>`,其中`DatabaseError`是自定义的错误类型。编写代码实现这个异步函数,并展示如何优雅地处理`Some`、`None`以及可能出现的数据库错误情况,同时要遵循Rust的异步编程最佳实践,例如使用`async/await`和合适的异步运行时。
11.0万 热度难度
编程语言Rust

知识考点

AI 面试

面试题答案

一键面试
use std::error::Error;

// 定义自定义数据结构
#[derive(Debug)]
struct SomeComplexData {
    // 自定义复杂数据结构的字段
    value: String,
}

// 定义DatabaseRecord结构体
#[derive(Debug)]
struct DatabaseRecord {
    id: i32,
    data: SomeComplexData,
}

// 定义DatabaseError错误类型
#[derive(Debug)]
struct DatabaseError(String);

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

impl Error for DatabaseError {}

// 模拟从数据库获取记录的异步函数
async fn get_database_record(id: i32) -> Result<Option<DatabaseRecord>, DatabaseError> {
    // 这里通常会包含实际的数据库查询逻辑,例如使用异步数据库驱动
    // 这里简单模拟返回数据
    if id == 1 {
        Ok(Some(DatabaseRecord {
            id,
            data: SomeComplexData {
                value: "example data".to_string(),
            },
        }))
    } else if id == 2 {
        Ok(None)
    } else {
        Err(DatabaseError("模拟数据库错误".to_string()))
    }
}

#[tokio::main]
async fn main() {
    let record_id = 1;
    match get_database_record(record_id).await {
        Ok(Some(record)) => {
            println!("获取到记录: {:?}", record);
        }
        Ok(None) => {
            println!("未找到记录");
        }
        Err(e) => {
            eprintln!("数据库错误: {}", e);
        }
    }
}

上述代码首先定义了自定义的数据结构SomeComplexDataDatabaseRecord,以及自定义错误类型DatabaseErrorget_database_record函数模拟了从数据库获取记录的异步操作,返回Result<Option<DatabaseRecord>, DatabaseError>。在main函数中,使用match语句优雅地处理了SomeNone以及可能出现的数据库错误情况。代码使用了async/await语法,并基于Tokio异步运行时(通过#[tokio::main]),遵循了Rust异步编程的最佳实践。