我正在使用Rust生成器,并且在每晚1.29.0下运行良好:
common_types.go:21:5: cannot use "cloud.google.com/go/pubsub".Client literal (type "cloud.google.com/go/pubsub".Client) as type SubscriptionMaker in assignment:
"cloud.google.com/go/pubsub".Client does not implement SubscriptionMaker (wrong type for Subscription method)
have Subscription(string) *"cloud.google.com/go/pubsub".Subscription
want Subscription(string) Receiver
但是,每晚版本1.34.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"),
}
}
}
包装在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
?答案 0 :(得分:4)
为什么在每晚Rust 1.29中运行的生成器代码在每晚1.34.0中给出错误?
因为这是一个每晚,不稳定功能,随时可能会更改,因此也会更改。
另请参阅:
为什么在最新版本中将
Generator
包裹在Pin
中会导致错误?
错误消息指出,Box<dyn Generator<Yield = u64, Return = &str>>
没有实现Generator
。
另请参阅:
为生成器使用
Pin
有什么用?为什么
resume
方法不再不安全?
resume
方法是不安全的,因为如果生成器具有自引用变量并且在两次调用resume
之间移动了它,则可能会引入内存不安全性。 Pin
阻止移动,从而消除了不安全因素。这是将不安全逻辑包装在仅公开安全接口的API中的经典示例。
另请参阅:
当我们删除生成器变量的类型时,为什么代码会起作用?
因为它不再是特征对象(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"),
}
}