能否不使用嵌套闭包创建Rust生成器?
Rust中能否不使用嵌套闭包创建生成器?
目前Rust稳定版里,没办法直接跳过闭包/生成器表达式,在函数体内通过yield来创建返回生成器的函数,必须借助|| { ... }这种生成器闭包的形式。
现状与原因
Rust的生成器目前仍处于不稳定状态,它本质是实现了Generator trait的匿名类型。当前语法规则要求,必须通过生成器表达式(闭包形式)来生成这个匿名类型——普通函数的函数体并不支持yield关键字,只有生成器闭包、async块/函数这类特殊语法结构才允许使用yield。
你给出的当前可行写法(修正后):
fn do_thing(i: i32) -> impl Generator<Yield = i32, Return = ()> { || { for x in 0..i { yield x; } } }
而你期望的这种直接在函数体写yield的写法,目前编译器会判定为语法错误,没有对应的语法支持:
// 目前Rust不支持该写法 fn do_thing(i: i32) -> impl Generator<Yield = i32, Return = ()> { for x in 0..i { yield x; } }
与async函数的对比差异
你提到async函数不需要额外闭包,这是因为Rust为async设计了专门的顶层语法糖:编译器会自动将async函数的函数体转换为一个实现Future的生成器(底层依赖生成器机制,但语法上做了封装)。但生成器本身还没有得到同等的顶层语法支持,Rust没有提供"generator函数"这类语法糖,因此必须显式写出生成器闭包来返回对应类型。
补充:不稳定版本的尝试
在Rust nightly版中,可以使用实验性的#[generator]属性来接近你想要的写法,但这依然属于不稳定特性,且语法上仍需要额外标注,示例如下:
#![feature(generators, generator_trait)] use std::ops::{Generator, GeneratorState}; #[generator] fn do_thing(i: i32) -> impl Generator<Yield = i32, Return = ()> { for x in 0..i { yield x; } }
不过这个特性的设计仍在迭代中,未来可能有变化,且无法在稳定版中使用。
内容的提问来源于stack exchange,提问作者A.Z.
相关产品推荐
相关产品推荐

