Closed by23 closed 4 years ago
@by23 收到。感谢反馈
现在这段代码也需要改一下,因为Generator这个trait的resume方法签名已经变更为:
fn resume(self: Pin<&mut Self>, arg: R) -> GeneratorState<Self::Yield, Self::Return>;
这意味着需要传递arg参数给方法。
上面的代码变更为:
#![feature(generators, generator_trait)]
use std::ops::Generator;
use std::pin::Pin;
fn main() {
let mut gen = || {
yield 1;
yield 2;
yield 3;
return 4;
};
for _ in 0..4 {
// 多传入了一个空的unit给resume方法
let c = Pin::new(&mut gen).resume(());
println!("{:?}", c);
}
}
@kid143 感谢反馈
@kid143 这个修改应该是为了支持 no_std 下的异步
#![feature(generators, generator_trait)]
use std::ops::Generator;
use std::pin::Pin;
fn main() {
let mut gen = || {
yield 1;
yield 2;
yield 3;
return 4;
};
for _ in 0..4 {
// 多传入了一个空的unit给resume方法
let c = Pin::new(&mut gen).resume(());
println!("{:?}", c);
}
}
生成的等价代码:
#![allow(unused)]
#![feature(generators, generator_trait)]
use std::ops::{Generator, GeneratorState};
use std::pin::Pin;
enum __Gen {
// (0) 初始状态
Start,
// (1) resume方法执行以后
State1(State1),
// (2) resume方法执行以后
State2(State2),
// (3) resume方法执行以后
State3(State3),
// (4) resume方法执行以后,正好完成
Done
}
struct State1 { x: u64 }
struct State2 { x: u64 }
struct State3 { x: u64 }
impl Generator for __Gen {
type Yield = u64;
type Return = u64;
fn resume(self: Pin<&mut Self>, _: ()) -> GeneratorState<u64, u64> {
let mut_ref = self.get_mut();
match std::mem::replace(mut_ref, __Gen::Done) {
__Gen::Start => {
*mut_ref = __Gen::State1(State1{x: 1});
GeneratorState::Yielded(1)
}
__Gen::State1(State1{x: 1}) => {
*mut_ref = __Gen::State2(State2{x: 2});
GeneratorState::Yielded(2)
}
__Gen::State2(State2{x: 2}) => {
*mut_ref = __Gen::State3(State3{x: 3});
GeneratorState::Yielded(3)
}
__Gen::State3(State3{x: 3}) => {
*mut_ref = __Gen::Done;
GeneratorState::Complete(4)
}
_ => {
panic!("generator resumed after completion")
}
}
}
}
fn main(){
let mut gen = {
__Gen::Start
};
for _ in 0..4 {
println!("{:?}", unsafe{ Pin::new(&mut gen).resume(())});
}
}
代码清单11-62 Rust生成器用法变更
以前的代码无法编译 新的代码如下
运行结果如下