Module std::async_iter
source · async_iterator
#79024)Expand description
可组合的异步迭代。
如果您发现自己使用某种异步集合,并且需要对所述集合的元素执行操作,您将很快遇到异步迭代器。 异步迭代器在惯用的异步 Rust 代码中大量使用,因此熟悉它们是值得的。
在解释更多内容之前,让我们讨论一下该模块的结构:
Organization
该模块主要是按类型来组织的:
- Traits 是核心部分:这些 traits 定义了存在什么样的异步迭代器以及您可以用它们做什么。这些 traits 的方法值得投入一些额外的学习时间。
- 函数提供了一些有用的方法来创建一些基本的异步迭代器。
- 结构体通常是该模块的 traits 上各种方法的返回类型。通常,您将需要查看创建
struct
的方法,而不是struct
本身。 有关原因的更多详细信息,请参见 实现异步迭代器。
就是这样! 让我们深入研究异步迭代器。
异步迭代器
这个模块的核心和灵魂是 AsyncIterator
trait。AsyncIterator
的核心是这样的:
trait AsyncIterator {
type Item;
fn poll_next(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Option<Self::Item>>;
}
Run与 Iterator
不同,AsyncIterator
区分了实现 AsyncIterator
时使用的 poll_next
方法和使用异步迭代器时使用的 (to-be-implemented) next
方法。
AsyncIterator
的消费者只需要考虑 next
,它在调用时会返回一个 future,它产生 Option<AsyncIterator::Item>
。
只要有元素,next
返回的 future 就会产生 Some(Item)
,一旦所有元素用完,就会产生 None
来指示迭代已完成。
如果我们正在等待异步解决问题,future 将等待异步迭代器再次准备好再次 yield。
单个异步迭代器可能会选择恢复迭代,因此再次调用 next
最终可能会或可能不会最终在某个时候再次产生 Some(Item)
。
AsyncIterator
的完整定义还包括许多其他方法,但它们是默认方法,建立在 poll_next
之上,因此您可以免费获得它们。
实现异步迭代器
创建自己的异步迭代器涉及两个步骤:创建一个 struct
来保存异步迭代器的状态,然后为该 struct
实现 AsyncIterator
。
让我们创建一个名为 Counter
的异步迭代器,它从 1
计数到 5
:
#![feature(async_iterator)]
// 首先,结构体:
/// 一个从 1 计数到 5 的异步迭代器
struct Counter {
count: usize,
}
// 我们希望计数从一开始,所以让我们添加一个 new() 方法来提供帮助。
// 这不是严格必要的,但很方便。
// 请注意,我们将 `count` 从零开始,我们将在下面的 `poll_next () ` 的实现中看到其原因。
impl Counter {
fn new() -> Counter {
Counter { count: 0 }
}
}
// 然后,我们为我们的 `Counter` 实现 `AsyncIterator`:
impl AsyncIterator for Counter {
// 我们将使用 usize 进行计数
type Item = usize;
// poll_next() 是唯一需要的方法
fn poll_next(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Option<Self::Item>> {
// 增加我们的数量。这就是为什么我们从零开始。
self.count += 1;
// 检查我们是否已经完成计数。
if self.count < 6 {
Poll::Ready(Some(self.count))
} else {
Poll::Ready(None)
}
}
}
RunLaziness
异步迭代器是惰性的。这意味着仅仅创建一个异步迭代器并不能做很多事情。在您调用 poll_next
之前,什么都不会发生。
当创建一个异步迭代器仅仅为了它的副作用时,这有时是一个混乱的根源。
编译器将警告我们这种行为:
warning: unused result that must be used: async iterators do nothing unless polled
Structs
- FromIterExperimental从迭代器创建的异步迭代器。
Traits
- AsyncIteratorExperimental用于处理异步迭代器的 trait。
Functions
- from_iterExperimental将迭代器转换为异步迭代器。