1 个不稳定版本
0.1.0 | 2024年1月13日 |
---|
#882 in 异步
67KB
2K SLoC
Async Iter
此库提供了Rust的Iterator
特性和异步版本的实用工具。
快速入门
添加到依赖项
将async-iter添加到依赖项
cargo add asynciter
实用工具入口
然后,导入基本特性
use asynciter::{
// This offers standard api, just like the `std::iter::Iterator`
AsyncIterator,
// use `.aiter()` to convert a synchronous iterator
// into an asynchronous one
ToAsyncIterator,
// use `.into_aiter()` to convert a synchronous iterable object
// into an asynchronous iterator
IntoAsyncIterator,
}
API调用栈
所有API名称和限制都与std相同。您只需要将.iter()
或.into_iter()
更改为.aiter()
或.into_aiter()
assert_eq!(
["Hello%", "World%", "!"]
.into_aiter()
.map(|s| s.to_ascii_lowercase())
.intersperse(" ".into())
.flat_map(|s| s.chars().filter(|s| s != &'%').collect::<Vec<_>>())
.collect::<String>()
.await,
"hello world !"
);
异步替代方案
如果您想在迭代器中使用异步函数,以a
为前缀的api将接受返回Future
的函数,其工作方式与同步函数相同
async fn do_async(val: i32) -> String {
format!("Async! {val}")
}
(0..=10)
.aiter()
// `amap` accepts `FnMut(Item) -> Future<Output>`
.amap(do_async)
// `afor_each` accepts `FnMut(Item) -> Future<Output = ()>`
.afor_each(|s| async move {
println!("{s}");
})
.await;
等待的异步迭代器
如果您有一个产生Future
的迭代器,请使用.awaited()
将它们转换为AsyncIterator
// impl Iterator<Output: Future<Output = i32>>
let sync_it = (0..10).map(|s| async move { s + 1 });
// impl AsyncIterator<Output = i32>
let async_it = sync_it.aiter().awaited();
内部实现
所有内部实现都可以在asynciter::iterimpl
模块中找到,并公开导出,但不建议直接使用。
注意
对于接受FnXXX(&Self::Item) -> Future
的api,还有一个额外的限制。由于Future
将在函数调用之后使用,引用可能会超出函数调用的生命周期,导致编译器失败。为了保持代码的安全性,引用必须在Future
之外进行处理和释放。
例如,以下代码将无法通过编译器检查
(0..10)
.aiter()
.afilter(
|s| // Here we accept the reference
async move {
*s < 5 // And we use it here.
// The reference will live longer than the function,
// which is not safe.
}
)
相反,我们必须使用以下解决方案
(0..10)
.map(|s| s.to_string())
.aiter()
.afilter(|s| {
let s = s.clone(); // Here we save the reference
// by cloning the value
async move {
// do something
false
}
})
.for_each(|_| {}).await;
许可证
本项目受MIT许可证或Apache V2.0许可证许可。