面试题答案
一键面试1. 错误处理策略
- 控制台输出错误处理:使用
Result
类型捕获控制台输出操作可能抛出的错误,并进行适当的处理,例如记录错误日志。 - 异步任务错误传播:在异步函数中,通过
?
操作符将错误向上传播,让调用者决定如何处理。 - 重试机制:使用
futures::future::retry
或手动实现重试逻辑,在错误发生时进行一定次数的重试。
2. 关键代码片段
以下是使用Tokio框架的示例代码:
use std::io::{self, Write};
use futures::future::retry;
use tokio::task;
// 模拟向控制台输出数据的异步函数
async fn print_to_console(data: &str) -> Result<(), io::Error> {
let mut stdout = io::stdout();
stdout.write_all(data.as_bytes())?;
stdout.flush()?;
Ok(())
}
// 模拟向日志服务发送数据的异步函数
async fn send_to_log_service(data: &str) -> Result<(), Box<dyn std::error::Error>> {
// 这里假设网络波动可能导致错误
if rand::random::<bool>() {
Err("Network error".into())
} else {
Ok(())
}
}
// 主异步任务
async fn main_task() -> Result<(), Box<dyn std::error::Error>> {
let data = "大量需要输出的数据";
// 处理控制台输出错误
let console_result = print_to_console(data).await;
if let Err(e) = console_result {
eprintln!("控制台输出错误: {}", e);
}
// 处理日志服务发送错误并进行重试
let log_result = retry(
|attempt| async move {
match send_to_log_service(data).await {
Ok(_) => Ok(()),
Err(e) => {
eprintln!("第{}次尝试向日志服务发送数据失败: {}", attempt, e);
if attempt < 3 {
// 重试3次
Err(futures::future::Retry::Retry)
} else {
Err(futures::future::Retry::Abort)
}
}
}
}
).await;
if let Err(e) = log_result {
eprintln!("向日志服务发送数据最终失败: {}", e);
}
Ok(())
}
fn main() {
task::block_on(main_task()).unwrap();
}
3. 核心实现思路
- 控制台输出:
print_to_console
函数使用标准库的io::Write
特性向控制台输出数据,通过?
操作符传播可能的io::Error
。在主任务中捕获并打印错误。 - 异步任务错误传播:
main_task
函数通过?
操作符传播内部函数的错误,也可以在内部处理错误,例如记录错误日志。 - 重试机制:使用
futures::future::retry
函数,在每次尝试失败时检查重试次数,决定是否继续重试。如果重试次数达到上限,则终止重试并返回错误。