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
130
131
132
133
134
135
use crate::marker::Unpin;
use crate::pin::Pin;

/// 恢复生成器的结果。
///
/// 该枚举从 `Generator::resume` 方法返回,并指示生成器的可能返回值。
/// 当前,这对应于悬挂点 (`Yielded`) 或终止点 (`Complete`)。
///
#[derive(Clone, Copy, PartialEq, PartialOrd, Eq, Ord, Debug, Hash)]
#[lang = "generator_state"]
#[unstable(feature = "generator_trait", issue = "43122")]
pub enum GeneratorState<Y, R> {
    /// 生成器挂起了一个值。
    ///
    /// 此状态表明生成器已被挂起,并且通常对应于 `yield` 语句。
    /// 该变体中提供的值对应于传递给 `yield` 的表达式,并允许生成器在每次产生时提供一个值。
    ///
    ///
    Yielded(Y),

    /// 生成器完成并返回一个值。
    ///
    /// 此状态表明生成器已使用提供的值完成了执行。
    /// 生成器返回 `Complete` 后,再次调用 `resume` 将被视为程序员错误。
    ///
    Complete(R),
}

/// 由内置生成器类型实现的 trait。
///
/// 生成器,通常也称为协程,目前是 Rust 中的一个实验性语言特性。
/// [RFC 2033] 中添加的生成器目前主要用于为 async/await 语法提供构建块,但可能会扩展为还为迭代器和其他原语提供符合人体工程学的定义。
///
///
/// 生成器的语法和语义不稳定,将需要进一步的 RFC 来稳定。但是,此时的语法类似于闭包:
///
/// ```rust
/// #![feature(generators, generator_trait)]
///
/// use std::ops::{Generator, GeneratorState};
/// use std::pin::Pin;
///
/// fn main() {
///     let mut generator = || {
///         yield 1;
///         "foo"
///     };
///
///     match Pin::new(&mut generator).resume(()) {
///         GeneratorState::Yielded(1) => {}
///         _ => panic!("unexpected return from resume"),
///     }
///     match Pin::new(&mut generator).resume(()) {
///         GeneratorState::Complete("foo") => {}
///         _ => panic!("unexpected return from resume"),
///     }
/// }
/// ```
///
/// 更多关于生成器的文档可以在 [未稳定的书][unstable book] 中找到。
///
/// [RFC 2033]: https://github.com/rust-lang/rfcs/pull/2033
/// [unstable book]: ../../unstable-book/language-features/generators.html
///
///
///
///
#[lang = "generator"]
#[unstable(feature = "generator_trait", issue = "43122")]
#[fundamental]
pub trait Generator<R = ()> {
    /// 此生成器产生的值的类型。
    ///
    /// 此关联类型对应于 `yield` 表达式以及每次生成器产生时都允许返回的值。
    ///
    /// 例如,作为一个迭代器的迭代器可能将这种类型作为 `T` 进行迭代。
    ///
    type Yield;

    /// 此生成器返回的值的类型。
    ///
    /// 这对应于使用 `return` 语句从生成器返回的类型,或隐式作为生成器字面量的最后一个表达式返回的类型。
    /// 例如,futures 将其用作 `Result<T, E>`,因为它代表完整的 future。
    ///
    ///
    type Return;

    /// 恢复此生成器的执行。
    ///
    /// 此函数将恢复生成器的执行,如果尚未生成,则开始执行。
    /// 该调用将返回到生成器的最后一个暂停点,从最新的 `yield` 恢复执行。
    /// 生成器将继续执行,直到它产生或返回,此时该函数将返回。
    ///
    /// # 返回值
    ///
    /// 从此函数返回的 `GeneratorState` 枚举指示生成器在返回时处于什么状态。
    /// 如果返回了 `Yielded` 变体,则生成器已达到暂停点,并且已产生一个值。
    /// 此状态下的生成器可在稍后恢复。
    ///
    /// 如果返回 `Complete`,则生成器将完全完成所提供的值。再次恢复生成器是无效的。
    ///
    /// # Panics
    ///
    /// 如果先前已返回 `Complete` 变体后调用此函数,就可能会出现 panic。
    /// 尽管在 `Complete` 之后恢复时,将语言中的生成器字面量保证为 panic,但对于 `Generator` trait 的所有实现均不能保证。
    ///
    ///
    ///
    ///
    ///
    ///
    ///
    ///
    fn resume(self: Pin<&mut Self>, arg: R) -> GeneratorState<Self::Yield, Self::Return>;
}

#[unstable(feature = "generator_trait", issue = "43122")]
impl<G: ?Sized + Generator<R>, R> Generator<R> for Pin<&mut G> {
    type Yield = G::Yield;
    type Return = G::Return;

    fn resume(mut self: Pin<&mut Self>, arg: R) -> GeneratorState<Self::Yield, Self::Return> {
        G::resume((*self).as_mut(), arg)
    }
}

#[unstable(feature = "generator_trait", issue = "43122")]
impl<G: ?Sized + Generator<R> + Unpin, R> Generator<R> for &mut G {
    type Yield = G::Yield;
    type Return = G::Return;

    fn resume(mut self: Pin<&mut Self>, arg: R) -> GeneratorState<Self::Yield, Self::Return> {
        G::resume(Pin::new(&mut *self), arg)
    }
}