在內部,async fn建立一個狀態機型別,其中包含每個正在等待的子Future。那麼,當涉及到遞迴的時候怎麼辦呢?
示例1
- 原始碼
use futures;
async fn first() {}
async fn second() {}
async fn foo() {
first().await;
second().await;
}
fn main() {
futures::executor::block_on(foo());
}
配置
[dependencies] futures = "0.3"
說明
編譯器會async塊生成對應的結構體,上面的例子生成的結構體如下:
enum Foo {
First(first),
Second(second),
}
示例2
那麼,當對應到遞迴會是什麼樣的呢?
- 原始碼
use futures;
fn re() {
re().await;
re().await;
}
fn main() {
futures::executor::block_on(re());
}
- 說明
執行該程式報錯。編譯器對應的展開可能如下:
enum Re {
First(Re),
Second(Re),
}
顯然,這樣創造了一個無限尺寸大小的型別,因此報錯。
解決辦法
那麼我們要使用遞迴怎麼辦?只需要使用Box就可以了,不過對應的限制是需要變成同步函式。
- 原始碼
use futures::future::{BoxFuture, FutureExt};
fn re() -> BoxFuture<'static, ()> {
async move {
re().await;
re().await;
}.boxed()
}
fn main() {
re();
}
- 配置
[dependencies] futures = "0.3"
執行ok。
本作品採用《CC 協議》,轉載必須註明作者和本文連結