rust 如何在结构字段中表示不透明类型

vatpfxk5  于 2022-11-12  发布在  其他
关注(0)|答案(1)|浏览(141)

我正在使用genwaiter crate for generator函数来实现单线程的“多任务”。我有这段代码来创建一个新的线程,并将一个生成器传递给它,但我正在努力寻找如何表示gen!()返回的impl Future类型。

use genawaiter::rc::{gen, Gen};
use genawaiter::yield_;
struct Thread {
    function: genawaiter::rc::Gen<(), Option<Sprite>, /*What can go here?*/>,
}

struct Sprite {/*fields here*/}

fn main() {
    let thread1 = Thread {
        function: gen!({
            let object: Option<&mut Sprite> = yield_!(());
            // do stuff with `object`
            println!("Hi");
        }),
    };
}

gen!()宏传回的型别为。

genawaiter::rc::Gen<(),Option<Sprite>,impl Future<Output = ()>>

如果我尝试将其设置为function字段的类型,则会收到以下错误消息:
第一个
如果我尝试将此EmptyFuture结构体放入function字段中,它也不起作用,并且我会收到以下错误消息:

error[E0308]: mismatched types
  --> src/main.rs:27:19
   |
27 |            function: gen!({
   |   ___________________^____-
   |  |___________________|
   | ||
28 | ||             let object: Option<Sprite> = yield_!(());
29 | ||             println!("Hi");
30 | ||         }),
   | ||_________-^ expected struct `EmptyFuture`, found opaque type
   |  |_________|
   |            the found `async` block
   |
  ::: /home/calvin/.rustup/toolchains/stable-x86_64-unknown-linux-gnu/lib/rustlib/src/rust/library/core/src/future/mod.rs:72:43
   |
72 |    pub const fn from_generator<T>(gen: T) -> impl Future<Output = T::Return>
   |                                              ------------------------------- the found opaque type
   |
   = note: expected struct `genawaiter::rc::Gen<_, _, EmptyFuture>`
              found struct `genawaiter::rc::Gen<_, _, impl Future<Output = ()>>`
   = note: this error originates in the macro `gen` (in Nightly builds, run with -Z macro-backtrace for more info)

我能在stackoverflow上找到的唯一半相关的东西是this,但那是关于函数/返回/不透明类型的。
如何在我的结构体中表示不透明类型?另外,它是空类型(impl Future<Output = ()>)还是其他结构体(impl Future<Output = SomeStruct>)有区别吗?
编辑:
我尝试了Box<dyn Future<Output = ()>>,但出现以下错误:

error[E0277]: `(dyn Future<Output = ()> + 'static)` cannot be unpinned
   --> src/target/mod.rs:325:15
    |
325 |     function: genawaiter::rc::Gen<(), Option<Sprite>, Box<dyn Future<Output = ()>>>,
    |               ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `Unpin` is not implemented for `(dyn Future<Output = ()> + 'static)`
    |
    = note: consider using `Box::pin`
    = note: required because of the requirements on the impl of `Future` for `Box<(dyn Future<Output = ()> + 'static)>`
note: required by a bound in `genawaiter::rc::Gen`
   --> /home/calvin/.cargo/registry/src/github.com-1ecc6299db9ec823/genawaiter-0.99.1/src/rc/generator.rs:11:25
    |
11  | pub struct Gen<Y, R, F: Future> {
    |                         ^^^^^^ required by this bound in `genawaiter::rc::Gen`

For more information about this error, try `rustc --explain E0277`.

我按照编译器的建议将其更改为Pin<Box<dyn Future<Output = ()>>>,但现在我得到了一个与以前类似的错误:

error[E0308]: mismatched types
  --> src/main.rs:28:19
   |
28 |            function: gen!({
   |   ___________________^____-
   |  |___________________|
   | ||
29 | ||             let object: Option<Sprite> = yield_!(());
30 | ||             println!("Hi");
31 | ||         }),
   | ||_________-^ expected struct `Pin`, found opaque type
   |  |_________|
   |            the found `async` block
   |
  ::: /home/calvin/.rustup/toolchains/stable-x86_64-unknown-linux-gnu/lib/rustlib/src/rust/library/core/src/future/mod.rs:72:43
   |
72 |    pub const fn from_generator<T>(gen: T) -> impl Future<Output = T::Return>
   |                                              ------------------------------- the found opaque type
   |
   = note: expected struct `genawaiter::rc::Gen<_, _, Pin<Box<(dyn Future<Output = ()> + 'static)>>>`
              found struct `genawaiter::rc::Gen<_, _, impl Future<Output = ()>>`
   = note: this error originates in the macro `gen` (in Nightly builds, run with -Z macro-backtrace for more info)

For more information about this error, try `rustc --explain E0308`.
au9on6nz

au9on6nz1#

你可以尝试将trait对象装箱,也就是使用Box<dyn Future<Output = ()>>,这将为每个创建的future花费一次分配,但这是最简单的解决方案,而且实际上是唯一一个你不(或不能)命名类型的解决方案。

相关问题