use std::future::Future;
use tokio::runtime::Runtime;
async fn fetch_data() -> i32 {
// 模拟从网络获取数据,这里简单返回固定值
10
}
fn main() {
let rt = Runtime::new().unwrap();
let result = rt.block_on(async {
let mut futures = Vec::new();
for _ in 0..3 {
futures.push(fetch_data());
}
let results: Vec<i32> = futures::future::join_all(futures).await;
results.iter().sum::<i32>()
});
println!("计算总和: {}", result);
}
异步函数在Rust并发编程中的优势
- 非阻塞I/O:异步函数允许在等待I/O操作(如网络请求或磁盘读取)完成时,线程不会被阻塞,从而可以继续执行其他任务,提高了资源利用率和程序的整体性能。
- 轻量级线程:Rust的异步运行时(如Tokio)使用的是轻量级线程(协程),相比操作系统线程,创建和销毁的开销更小,适合处理大量并发任务。
- 简洁的代码结构:异步函数使用
async/await
语法,使异步代码看起来更像同步代码,提高了代码的可读性和可维护性。
在这种并发场景下处理错误
- Result类型:在
fetch_data
函数中,可以返回Result<T, E>
类型,其中T
是成功时返回的数据类型,E
是错误类型。例如:
async fn fetch_data() -> Result<i32, String> {
// 模拟从网络获取数据,这里简单返回固定值
Ok(10)
}
- 处理错误:在
join_all
后,可以使用map
或filter_map
来处理每个结果中的错误。例如:
let results: Vec<Result<i32, String>> = futures::future::join_all(futures).await;
let sum: i32 = results.into_iter()
.filter_map(|result| result.ok())
.sum();
在这种并发场景下资源管理
- RAII原则:Rust的资源管理遵循RAII(Resource Acquisition Is Initialization)原则,当异步函数结束时,其局部变量(包括打开的文件、网络连接等资源)会自动释放。
- Drop Trait:对于自定义类型,可以实现
Drop
trait来定义资源释放逻辑,确保在异步函数结束或变量超出作用域时,资源能够被正确释放。