我正在尝试使用新的async
/ await
语法,std::future::Future
和最近的Tokio版本来实现。我正在使用Tokio 0.2.0-alpha.4
和Rust 1.39.0-nightly
。
我尝试过的其他事情包括:
Box<dyn>
我无法获得最低的工作版本,所以这是我要实现的目标的简化版本:
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(())
}
[StorableAsyncFn
在这里未定义,这是我尝试定义的类型。
因此,此代码当然无法编译,并出现以下错误:
error[E0412]: cannot find type `StorableAsyncFn` in this scope
让我们以此作为我们的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>
的语法糖。
我们将结构设为泛型,并在匹配的泛型上放置一个特征绑定。在实际代码中,您可能想对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;
}
另请参见: