面试题答案
一键面试设计思路
- 定义错误类型:为了处理
fetch_data
可能出现的各种错误,定义一个统一的错误枚举类型,包含网络错误、解析错误等具体错误变体。 - 在
AsyncDataFetcher
trait 中返回错误:fetch_data
方法返回Result
类型,将定义的错误类型作为Err
变体。 - 并发调用时的错误处理:使用
futures::future::join_all
并发调用多个AsyncDataFetcher
实现的fetch_data
方法。在处理结果时,将所有错误收集起来返回给上层调用者。
关键代码片段
use std::fmt;
use futures::future::join_all;
use std::error::Error;
// 定义错误类型
#[derive(Debug)]
enum DataFetchError {
NetworkError,
ParseError,
// 其他可能的错误变体
}
impl fmt::Display for DataFetchError {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match self {
DataFetchError::NetworkError => write!(f, "Network error occurred"),
DataFetchError::ParseError => write!(f, "Parse error occurred"),
}
}
}
impl Error for DataFetchError {}
// 定义 AsyncDataFetcher trait
trait AsyncDataFetcher {
async fn fetch_data(&self) -> Result<String, DataFetchError>;
}
// 示例实现
struct ExampleFetcher;
impl AsyncDataFetcher for ExampleFetcher {
async fn fetch_data(&self) -> Result<String, DataFetchError> {
// 模拟网络请求和解析
Ok("data".to_string())
}
}
// 并发调用多个 AsyncDataFetcher 实现并处理错误
async fn fetch_all_data(fetchers: Vec<Box<dyn AsyncDataFetcher>>) -> Result<Vec<String>, Vec<DataFetchError>> {
let futures = fetchers.into_iter().map(|fetcher| fetcher.fetch_data());
let results = join_all(futures).await;
let mut successes = Vec::new();
let mut errors = Vec::new();
for result in results {
match result {
Ok(data) => successes.push(data),
Err(e) => errors.push(e),
}
}
if errors.is_empty() {
Ok(successes)
} else {
Err(errors)
}
}
在上述代码中:
DataFetchError
枚举定义了可能出现的错误类型。AsyncDataFetcher
trait 中的fetch_data
方法返回Result<String, DataFetchError>
。fetch_all_data
函数并发调用多个AsyncDataFetcher
实现的fetch_data
方法,并收集所有错误返回给上层调用者。如果没有错误,返回成功获取的数据列表;如果有错误,返回错误列表。