#iterator #macro #yield #syntax #own #exploration #iterator-item

nightly macro iterator_item_macros

为iterator_item包提供过程宏

1个不稳定版本

0.1.0 2021年11月6日

#8#exploration


用于 iterator_item

MIT/Apache

18KB
334

Rust迭代器项:语法探索

这个crate是一个不稳定的生成器特性包装器,允许用户创建作为生成器的新的项。它遵循Propane crate的一般语义,但我对这个crate的兴趣是让感兴趣的人分叉它,并为这些项提出自己的语法。

以下语法受支持,需要用iterator_item宏的调用包围

区分符:*

fn* foo() yields i32 {
    for n in 0i32..10 {
        yield n;
    }
}

区分符:!

gen fn foo() -> i32 {
    for n in 0i32..10 {
        yield n;
    }
}

因为它是一个宏,所以它的效果不如本地语言特性好,并且错误信息更差,但已经尽力使其可用了。

关键字注意事项

通常,一个新的关键字需要一个版本来使用(以避免破坏使用它作为标识符的代码),并且在该版之前,该关键字需要使用保留语法,如k#yield。然而,Rust在Rust 0.8时将yield保留为关键字,并且从未释放。因此,Rust可以在没有过渡的情况下安全地使用该关键字。

Propane的设计决策

由于语义严重依赖于Propane,以下考虑也适用于此crate。

Propane的设计是为了允许用户编写生成器以实现迭代器。因此,其生成器在重要方面受到一些限制。以下是Propane的有意设计限制(也就是说,这些限制不是由于错误,而是有意不取消的)

  1. 丙烷发生器变成一个返回 implIterator 的函数;迭代器接口是用户可以使用生成器返回类型的唯一接口。
  2. 丙烷发生器只能返回 (),它不能在一个类型之后返回另一个有趣类型。? 运算符产生错误,然后在下一次恢复时返回。
  3. 丙烷发生器实现了 Unpin,并且不能是自引用的(与异步函数不同)。

关于 Unpin 要求的说明

由于 Iterator::next 的签名,在调用 next 之间移动迭代器始终是安全的。这使得无包、自引用迭代器不可靠。我们在设计迭代器 API 时没有 Pin

然而,通常,用户可以将无权数据推送到迭代器外部,这是他们无法使用 future 完成的。通常,future 最终必须是 'static,这样就可以启动它们,但迭代器通常以不需要拥有所有数据的方式被消耗。

因此,限制生成器不包含自引用可能是这种用例的充分条件。丙烷打算探索这种可能性。

依赖项

~1.5MB
~35K SLoC