在内部,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。