Skip to content

Latest commit

 

History

History
52 lines (43 loc) · 1.37 KB

7-3-Recursion.md

File metadata and controls

52 lines (43 loc) · 1.37 KB

在内部,async fn创建一个包含被.await的子Future的状态机。它使得递归的async fn有点棘手,因为结果状态机类型必须包含自身:

// This function:
async fn foo() {
    step_one().await;
    step_two().await;
}
// generates a type like this:
enum Foo {
    First(StepOne),
    Second(StepTwo),
}

// So this function:
async fn recursive() {
    recursive().await;
    recursive().await;
}

// generates a type like this:
enum Recursive {
    First(Recursive),
    Second(Recursive),
}

它将不能工作 - 我们创建一个无限大小的类型!编译器将会报错:

error[E0733]: recursion in an `async fn` requires boxing
 --> src/lib.rs:1:22
  |
1 | async fn recursive() {
  |                      ^ an `async fn` cannot invoke itself directly
  |
  = note: a recursive `async fn` must be rewritten to return a boxed future.

为了达到目的,我们不得不使用Box引入间接的引用。不幸的是,编译器的限制意味着仅将对recursive()的调用包装在Box :: pin中是不够的。为了使它工作,我们不得不使递归进一个非async的函数中,这个函数返回一个.boxed() async块。

use futures::future::{BoxFuture, FutureExt};

fn recursive() -> BoxFuture<'static, ()> {
    async move {
        recursive().await;
        recursive().await;
    }.boxed()
}