gpt4 book ai didi

asynchronous - 如何将异步函数存储在结构中并从结构实例中调用它?

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

我正在尝试使用新的 async 来实现这一目标/await语法,std::future::Future s 和最新版本的 Tokio。我正在使用 Tokio 0.2.0-alpha.4和 rust 1.39.0-nightly .

我尝试过的不同的东西包括:

  • 使用Box<dyn> s 表示我要存储在结构中的类型
  • 在结构定义中使用泛型

我无法完全获得最小工作版本,所以这里是我想要实现的简化版本:

async fn foo(x: u8) -> u8 {
2 * x
}

// type StorableAsyncFn = Fn(u8) -> dyn Future<Output = u8>;

struct S {
f: StorableAsyncFn,
}

#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error + Send + Sync>> {
let s = S { f: foo };

let out = (s.f)(1).await;

Ok(())
}

当然,这段代码无法编译并出现以下错误:

error[E0412]: cannot find type `StorableAsyncFn` in this scope

StorableAsyncFn此处未定义,这是我要定义的类型。

最佳答案

让我们用它作为我们的 Minimal, Reproducible Example :

async fn foo(x: u8) -> u8 {
2 * x
}

struct S {
foo: (),
}

async fn example() {
let s = S { foo };
}

它产生错误:

error[E0308]: mismatched types
--> src/main.rs:10:17
|
10 | let s = S { foo };
| ^^^ expected (), found fn item
|
= note: expected type `()`
found type `fn(u8) -> impl std::future::Future {foo}`

foo 的类型是一个接受 u8 的函数指针并返回某种实现特征 std::future::Future 的类型. async fn实际上只是转换 -> Foo 的语法糖进入-> impl Future<Output = Foo> .

我们使我们的结构通用,并在匹配的通用上放置一个特征绑定(bind)。在实际代码中,您可能希望对 Output 施加约束。关联类型,但本示例不需要它。然后我们可以像调用任何其他可调用成员字段一样调用该函数:

async fn foo(x: u8) -> u8 {
2 * x
}

struct S<F>
where
F: std::future::Future,
{
foo: fn(u8) -> F,
}

impl<F> S<F>
where
F: std::future::Future,
{
async fn do_thing(self) {
(self.foo)(42).await;
}
}

async fn example() {
let s = S { foo };
s.do_thing().await;
}

为了更加灵活,您可以使用另一个泛型来存储闭包,而不是仅强制使用函数指针:

struct S<C, F>
where
C: Fn(u8) -> F,
F: std::future::Future,
{
foo: C,
}

impl<C, F> S<C, F>
where
C: Fn(u8) -> F,
F: std::future::Future,
{
async fn do_thing(self) {
(self.foo)(42).await;
}
}

另见:

关于asynchronous - 如何将异步函数存储在结构中并从结构实例中调用它?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58173711/

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