5 个版本
0.1.4 | 2023 年 12 月 17 日 |
---|---|
0.1.3 | 2023 年 12 月 13 日 |
0.1.2 | 2023 年 9 月 5 日 |
0.1.1 | 2023 年 9 月 5 日 |
0.1.0 | 2023 年 9 月 5 日 |
#350 在 Rust 模式
每月 713 次下载
56KB
855 行
fauxgen - 稳定 Rust 中的假生成器
该包允许您在稳定的 Rust 中编写自己的生成器。它是通过在 async-await 之上构建自己的生成器来实现的。
入门
要获取该包,请运行
cargo add fauxgen
编写生成器
该包提供了两种不同的定义生成器的方式。第一种,也是最方便的,是作为命名顶级函数
#[fauxgen::generator(yield = i32)]
fn generator() {
r#yield!(1);
r#yield!(2);
}
第二种是使用 gen!
宏作为 lambda
use fauxgen::GeneratorToken;
let generator = fauxgen::gen!(|token: GeneratorToken<i32>| {
token.yield_(1).await;
token.yield_(2).await;
});
您还可以编写异步生成器
use std::time::Duration;
#[fauxgen::generator(yield = u32)]
async fn generator() {
for i in 0u32..10 {
tokio::time::sleep(Duration::from_millis(50)).await;
r#yield!(i * 2);
}
}
使用生成器
简单的生成器将实现 Iterator
或 Stream
,具体取决于它们是否是异步的。但是,为了足够简单以便执行此操作,生成器必须不返回值或不接受参数。大多数生成器很可能属于此类。
请注意,由于生成器基于异步,您需要在它们可以使用之前将它们固定
#[fauxgen::generator(yield = &'static str)]
fn yield_some_words() {
r#yield!("testing");
r#yield!("one");
r#yield!("two");
}
let gen = std::pin::pin!(yield_some_words());
let words: Vec<_> = gen.collect();
assert_eq!(words, vec!["testing", "one", "two"]);
更高级的生成器使用
生成器不仅限于仅产生值或作为迭代器。实际上,有三种不同的方式可以将值传递到或从生成器中
- 第一种,我们已经看到,是通过从生成器中产生一个值
- 第二种,是在生成器末尾返回一个值
- 第三种,是外部代码可以将参数传递到生成器的
resume
函数中。此时,产生表达式评估为该参数。
它们可以一起使用来完成更复杂的流处理类型工作。请参阅示例文件夹以了解如何使用它们的一些方式。
作为一个更简单的示例,此生成器将产生与传递给 resume
调用的相同值
#[fauxgen::generator(yield = T, arg = T)]
fn delay<T>() {
let mut value = argument!();
loop {
value = r#yield!(value);
}
}
请注意,为了获取 resume
的第一个参数,使用了 argument!
宏。其余的从 yield
宏返回,但没有对第一个参数进行产生调用。
另请参阅
- genawaiter 是原始的“在异步之上生成生成器”包。
依赖项
~145KB