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

标签 rust opaque-types

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

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 的类型字段,我收到此错误消息:

error[E0562]: `impl Trait` only allowed in function and inherent method return types, not in path
  --> src/main.rs:20:55
   |
20 |     function: genawaiter::rc::Gen<(), Option<Sprite>, impl Future<Output = ()>>,
   |                                                       ^^^^^^^^^^^^^^^^^^^^^^^^

For more information about this error, try `rustc --explain E0562`.
error: could not compile `testing` due to previous error
struct EmptyFuture{}
impl Future for EmptyFuture {
    type Output = ();

    fn poll(
        self: std::pin::Pin<&mut Self>,
        cx: &mut std::task::Context<'_>,
    ) -> std::task::Poll<Self::Output> {
        std::task::Poll::Ready(())
    }
}

如果我尝试把这个 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`.

最佳答案

您可以尝试拳击特征对象。那就是使用 Box<dyn Future<Output = ()>> .这将使您为每个创建的 future 花费一个分配,但这是最简单的解决方案。如果您不(或不能)命名类型,这实际上是唯一的。

关于rust - 如何在结构字段中表示不透明类型,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/74057864/

相关文章:

rust - 如何使用 axum 和 rust-embed 托管 SPA 文件并嵌入

rust - C 库释放来自 Rust 的指针

scala - 是否可以在 Scala 3 中导出顶级不透明类型?

memory - 如何有效地创建一个初始化为相同值的大型项目向量?

types - 向下转换 Rust 特征组合

mysql - 无法使用柴油箱从 mysql 数据库加载结果

c - 为什么这个分配做得不好?

Swift 不透明类型与协议(protocol)——文档推断协议(protocol)的功能不能嵌套

swift - 返回通用协议(protocol) swift 的特殊类型的方法