如何传递一个未来作为一个函数参数?



我习惯Scala的Future类型,在Future[..]中你包装任何你返回的对象来指定它。

我的Rust函数hello返回Query,我似乎无法将该结果作为Future<Output = Query>类型的参数传递。为什么不呢?我怎样才能打得更好呢?

当我试图传递future作为参数时发生失败:

use std::future::Future;
struct Person;
struct DatabaseError;
type Query = Result<Vec<Person>, DatabaseError>;
async fn hello_future(future: &dyn Future<Output = Query>) -> bool {
future.await.is_ok()
}
async fn hello() -> Query {
unimplemented!()
}
async fn example() {
let f = hello();
hello_future(&f);
}
fn main() {}

编译失败,报错:

error[E0277]: `&dyn Future<Output = Result<Vec<Person>, DatabaseError>>` is not a future
--> src/main.rs:9:5
|
9 |     future.await.is_ok()
|     ^^^^^^^^^^^^ `&dyn Future<Output = Result<Vec<Person>, DatabaseError>>` is not a future
|
= help: the trait `Future` is not implemented for `&dyn Future<Output = Result<Vec<Person>, DatabaseError>>`
= note: required by `poll`

async函数将返回实现Future特性的不透明值。这意味着您可以接受实现该特性的泛型类型。最简洁的语法是impl Trait,但是您也可以引入一个命名的泛型参数:

async fn hello_future(future: impl Future<Output = Query>) -> bool {
future.await.is_ok()
}
async fn example() {
let f = hello();
hello_future(f);
}

参见:

  • 可以等待一个&dyn Future吗?
  • 从' async fn '返回的未来具体类型是什么?
  • 为什么在传递性状作为函数参数时需要' impl ' ?
  • 当用作函数的参数类型或返回类型时,"impl"意味着什么?
  • 如何接受异步函数作为参数?

您也可以使用Pin<Box<dyn Future<Output = Query>>>作为参数:

async fn hello_future(future: Pin<Box<dyn Future<Output = Query>>>) -> bool {
future.await.is_ok()
}
...
async fn example() {
let f: impl Future<Output = Result<Vec<Person>, DatabaseError>> = hello();
hello_future(Box::pin(f));
}

区别在于impl Future是编译时调度。编译器为hello_future的每个类型实例化生成可执行代码。Pin<Box<...>>是运行时调度。只生成hello_future的可执行二进制代码的一个副本。

最新更新