Tec*_*dar 12 future rust async-await
use futures::{future, Future};
fn test() -> Box<dyn Future<Output = bool>> {
Box::new(future::ok::<bool>(true))
}
async fn async_fn() -> bool {
let result: bool = test().await;
return result;
}
fn main(){
async_fn();
println!("Hello!");
}
Run Code Online (Sandbox Code Playgroud)
错误:
use futures::{future, Future};
fn test() -> Box<dyn Future<Output = bool>> {
Box::new(future::ok::<bool>(true))
}
async fn async_fn() -> bool {
let result: bool = test().await;
return result;
}
fn main(){
async_fn();
println!("Hello!");
}
Run Code Online (Sandbox Code Playgroud)
Öme*_*den 12
根据实施:
impl<F> Future for Box<F>
where
F: Unpin + Future + ?Sized,
Run Code Online (Sandbox Code Playgroud)
盒装期货只是实现了Future特质里面将来时Box工具Unpin。
由于您的函数不保证返回的未来实现Unpin,因此您的返回值将被视为未实现Future。您将无法使用await它,因为您的类型基本上不是Future.
来自@Stargateur 的解决方案,为签名添加一个显式类型边界,有效(Playground):
fn test() -> Box<dyn Future<Output = Result<bool, ()>> + Unpin>
Run Code Online (Sandbox Code Playgroud)
如果您使用的是 futures-rs,则有一个辅助类型BoxFuture。您可以在BoxedFuture不明确说明的情况下使用Unpin:
use futures::future::BoxFuture;
fn test() -> BoxFuture<'static, Result<bool, ()>> {
Box::pin(async { Ok(true) })
}
Run Code Online (Sandbox Code Playgroud)
当谈到Boxand 时future,使用Box::pin代替几乎总是有意义的Box::new:
use std::pin::Pin;
use futures::{future, Future};
fn test() -> Pin<Box<dyn Future<Output = Result<bool, ()>>>> {
Box::pin(future::ok(true))
}
async fn async_fn() -> bool {
test().await.unwrap()
}
Run Code Online (Sandbox Code Playgroud)
原因很有趣。Pin有一个全面的实现Unpin:
impl<P> Unpin for Pin<P> where
P: Unpin,
Run Code Online (Sandbox Code Playgroud)
Box<T>它的内部是无条件的Unpin:
impl<T> Unpin for Box<T> where
T: ?Sized,
Run Code Online (Sandbox Code Playgroud)
所以 aPin<Box<dyn Future>>是一个未固定的Future. 一切正常,但为什么Box它本身没有?这是一个Deref阻碍的地方:
impl<T: ?Sized> Deref for Box<T> {
type Target = T;
}
Run Code Online (Sandbox Code Playgroud)
await期望一个 unpinned Future,并且Box<dyn Future>您创建的Box::new确实包含一个Future. 因此,它会自动取消引用,并且Unpin会丢失,除非您使用Box<dyn Future + Unpin>.
编辑:@ÖmerErden 关于为什么不起作用是正确的Box<dyn Future>。