1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129
//! 可组合的异步迭代。
//!
//! 如果 futures 是异步值,则流是异步迭代器。
//! 如果您发现自己具有某种异步集合,并且需要对所述集合的元素执行操作,那么您会很快遇到 'streams'。
//! 流在惯用的异步 Rust 代码中大量使用,因此值得熟悉它们。
//!
//! 在解释更多内容之前,让我们讨论一下该模块的结构:
//!
//! # Organization
//!
//! 该模块主要是按类型来组织的:
//!
//! * [Traits] 是核心部分:这些 traits 定义了存在什么样的流以及您可以用它们做什么。这些 traits 的方法值得投入一些额外的学习时间。
//! * 函数提供了一些有用的方法来创建一些基本流。
//! * 结构体通常是该模块的 traits 上各种方法的返回类型。通常,您将需要查看创建 `struct` 的方法,而不是 `struct` 本身。
//! 有关原因的更多详细信息,请参见 [实现流](#implementing-stream)。
//!
//! [Traits]: #traits
//!
//! 就是这样! 让我们深入的来研究流。
//!
//! # Stream
//!
//! 该模块的核心是 [`Stream`] trait。[`Stream`] 的核心如下所示:
//!
//! ```
//! # use core::task::{Context, Poll};
//! # use core::pin::Pin;
//! trait Stream {
//! type Item;
//! fn poll_next(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Option<Self::Item>>;
//! }
//! ```
//!
//! 与 `Iterator` 不同,`Stream` 区分了实现 `Stream` 时使用的 [`poll_next`] 方法和使用流时使用的 (to-be-implemented) `next` 方法。
//!
//! `Stream` 的使用者只需要考虑 `next`,当调用 `next` 时,它会返回 future 并产生 `Option<Stream::Item>`。
//!
//! 只要有元素,`next` 返回的 future 就会产生 `Some(Item)`,一旦所有元素用完,就会产生 `None` 来指示迭代已完成。
//! 如果我们正在等待异步解决某些事情,则 future 将等待,直到流准备好再次生成。
//!
//! 各个流可能选择恢复迭代,因此再次调用 `next` 可能会或可能最终不会在某个时候再次产生 `Some(Item)`。
//!
//! [`Stream`] 的完整定义还包括许多其他方法,但是它们是默认方法,基于 [`poll_next`] 构建,因此您可以免费获得它们。
//!
//! [`Poll`]: super::task::Poll
//! [`poll_next`]: Stream::poll_next
//!
//! # 实现流
//!
//! 创建自己的流涉及两个步骤:创建一个 `struct` 来保存流的状态,然后为该 `struct` 实现 [`Stream`]。
//!
//! 让我们创建一个名为 `Counter` 的流,它从 `1` 到 `5` 计数:
//!
//! ```no_run
//! #![feature(async_stream)]
//! # use core::stream::Stream;
//! # use core::task::{Context, Poll};
//! # use core::pin::Pin;
//!
//! // 首先,结构体:
//!
//! /// 从一数到五的流
//! struct Counter {
//! count: usize,
//! }
//!
//! // 我们希望计数从一开始,所以让我们添加一个 new() 方法来提供帮助。
//! // 这不是严格必要的,但很方便。
//! // 请注意,我们将 `count` 从零开始,我们将在下面的 `poll_next () ` 的实现中看到其原因。
//! impl Counter {
//! fn new() -> Counter {
//! Counter { count: 0 }
//! }
//! }
//!
//! // 然后,我们为 `Counter` 实现 `Stream`:
//!
//! impl Stream 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)
//! }
//! }
//! }
//! ```
//!
//! # Laziness
//!
//! 流是懒惰的。这意味着仅仅创建一个流并不能做很多事情。在您调用 `poll_next` 之前,什么都不会发生。
//! 当仅出于其副作用创建流时,这有时会引起混乱。
//! 编译器将警告我们这种行为:
//!
//! ```text
//! warning: unused result that must be used: streams do nothing unless polled
//! ```
//!
//!
//!
//!
//!
//!
//!
//!
//!
//!
//!
//!
//!
//!
//!
//!
//!
mod from_iter;
mod stream;
pub use from_iter::{from_iter, FromIter};
pub use stream::Stream;