面试题答案
一键面试1. 异步任务链中的错误传递与处理
在Rust的异步编程中,可以使用?
操作符来传递错误。当一个异步函数返回Result
类型时,如果操作失败,?
操作符会将错误从当前函数返回,从而中断函数执行。
use reqwest::Error as ReqwestError;
use some_database::Error as DatabaseError;
async fn fetch_data() -> Result<Vec<u8>, ReqwestError> {
// 模拟网络请求
reqwest::get("https://example.com").await?.bytes().await.map(Vec::from)
}
async fn write_to_database(data: Vec<u8>) -> Result<(), DatabaseError> {
// 模拟写入数据库
Ok(())
}
async fn main_async() -> Result<(), Box<dyn std::error::Error>> {
let data = fetch_data().await?;
write_to_database(data).await?;
Ok(())
}
2. 错误日志记录
可以使用log
crate来记录错误日志。在异步函数中,当Result
返回Err
时,记录错误信息。
use log::{error, info};
async fn main_async() -> Result<(), Box<dyn std::error::Error>> {
match fetch_data().await {
Ok(data) => {
match write_to_database(data).await {
Ok(_) => info!("Data written to database successfully"),
Err(e) => {
error!("Failed to write to database: {}", e);
return Err(Box::new(e));
}
}
}
Err(e) => {
error!("Failed to fetch data: {}", e);
return Err(Box::new(e));
}
}
Ok(())
}
3. 错误类型转换
为了实现更统一的错误处理接口,可以自定义一个错误类型,并实现从其他错误类型转换到自定义错误类型。
use std::fmt;
#[derive(Debug)]
enum MyAppError {
NetworkError(ReqwestError),
DatabaseError(DatabaseError),
}
impl fmt::Display for MyAppError {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match self {
MyAppError::NetworkError(e) => write!(f, "Network error: {}", e),
MyAppError::DatabaseError(e) => write!(f, "Database error: {}", e),
}
}
}
impl std::error::Error for MyAppError {}
impl From<ReqwestError> for MyAppError {
fn from(e: ReqwestError) -> Self {
MyAppError::NetworkError(e)
}
}
impl From<DatabaseError> for MyAppError {
fn from(e: DatabaseError) -> Self {
MyAppError::DatabaseError(e)
}
}
async fn main_async() -> Result<(), MyAppError> {
let data = fetch_data().await?;
write_to_database(data).await?;
Ok(())
}
4. Result
与Option
在错误处理上的主要区别及适用场景
- 区别:
Result
枚举用于表示可能成功或失败的操作,Ok(T)
表示成功并包含结果值T
,Err(E)
表示失败并包含错误类型E
。Option
枚举用于表示可能存在或不存在的值,Some(T)
表示存在值T
,None
表示不存在值。Option
不携带错误信息,更侧重于值的有无。
- 适用场景:
Result
适用于操作可能会因为各种原因(如I/O错误、网络错误、数据库错误等)而失败的情况,需要明确错误类型以进行针对性处理。Option
适用于值的存在与否是一种正常的业务逻辑情况,例如在集合中查找元素,找不到时返回None
,而不是因为错误导致查找失败。