我习惯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
的可执行二进制代码的一个副本。