【发布时间】:2019-06-18 22:32:09
【问题描述】:
我正在使用 Rust 生成器,它在夜间 1.29.0 中运行良好:
#![feature(generators, generator_trait)]
use std::ops::{Generator, GeneratorState};
fn main() {
let mut generator: Box<dyn Generator<Yield = u64, Return = &str>> = Box::new(move || {
yield 1;
return "foo";
});
unsafe {
match generator.resume() {
GeneratorState::Yielded(1) => {
println!("Yielded");
}
_ => panic!("unexpected return from resume"),
}
match generator.resume() {
GeneratorState::Complete("foo") => {
println!("Completed");
}
_ => panic!("unexpected return from resume"),
}
}
}
但是,夜间版本 1.34.0 要求将 Generator 包裹在 Pin 中,但是当我将 Generator 包裹到 Pin 中时,代码不再起作用。
#![feature(generators, generator_trait)]
use std::ops::{Generator, GeneratorState};
use std::pin::Pin;
fn main() {
let mut generator: Box<dyn Generator<Yield = u64, Return = &str>> = Box::new(move || {
yield 1;
return "foo";
});
match Pin::new(&mut generator).resume() {
GeneratorState::Yielded(1) => {
println!("Yielded");
}
_ => panic!("unexpected return from resume"),
}
match Pin::new(&mut generator).resume() {
GeneratorState::Complete("foo") => {
println!("Completed");
}
_ => panic!("unexpected return from resume"),
}
}
并且代码给出了以下错误。
error[E0599]: no method named `resume` found for type `std::pin::Pin<&mut std::boxed::Box<dyn std::ops::Generator<Yield = u64, Return = &str>>>` in the current scope
--> src/main.rs:12:36
|
12 | match Pin::new(&mut generator).resume() {
| ^^^^^^
|
= note: the method `resume` exists but the following trait bounds were not satisfied:
`std::boxed::Box<dyn std::ops::Generator<Yield = u64, Return = &str>> : std::ops::Generator`
当我删除生成器的类型时,它工作正常:
let mut generator = Box::new(move || {
yield 1;
return "foo"
});
我有几个问题:
- 为什么在最新版本中将
Generator包裹在Pin中会出现错误? - 生成器使用
Pin有什么用(因为它会阻止指针的值被移动),我不明白Pin和Generator之间的关系? - 为什么当我们删除
generator变量的类型时代码会起作用? - 为什么
resume方法不再是unsafe?
【问题讨论】: