gpt4 book ai didi

rust - 为什么在 nightly Rust 1.29 中工作的生成器在 nightly 1.34.0 中出错?

转载 作者:行者123 更新时间:2023-11-29 08:12:00 24 4
gpt4 key购买 nike

我正在使用 Rust 生成器,它在 nightly 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"),
}
}
}

但是,nightly 版本 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 变量的类型时代码仍然有效?
  • 为什么 resume 方法不再不安全

最佳答案

Why does generator code that was working in nightly Rust 1.29 give an error in Nightly 1.34.0?

因为这是一个每晚不稳定的特性,它可能随时改变,它已经改变了。

另见:

Why does wrapping the Generator in Pin give the error in the latest version?

如错误消息所述,Box<dyn Generator<Yield = u64, Return = &str>>没有实现 Generator .

另见:

What's the use of using the Pin for the generator?

Why is the resume method no longer unsafe?

resume方法是不安全的,因为如果生成器有一个自引用变量并且它在对 resume 的两次调用之间移动,则可能会引入内存不安全。 . Pin阻止移动,从而消除不安全性。这是在仅公开安全接口(interface)的 API 中包装不安全逻辑的典型示例。

另见:

Why does the code work when we remove the type for generator variable?

因为它不再是特征对象 (Box<dyn Generator>),而只是一个盒装混凝土生成器。

另见:


我会这样写

#![feature(generators, generator_trait)]

use std::ops::{Generator, GeneratorState};

fn main() {
let mut generator = Box::pin(move || {
yield 1;
"foo"
});

match generator.as_mut().resume() {
GeneratorState::Yielded(1) => println!("Yielded"),
_ => panic!("unexpected return from resume"),
}
match generator.as_mut().resume() {
GeneratorState::Complete("foo") => println!("Completed"),
_ => panic!("unexpected return from resume"),
}
}

关于rust - 为什么在 nightly Rust 1.29 中工作的生成器在 nightly 1.34.0 中出错?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56657852/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com