Procedural macro for recursive async functions.
- Documentation
- Cargo package: async-recursion
Consider the following recursive implementation of the fibonacci numbers:
asyncfnfib(n:u32) -> u32{match n {0 | 1 => 1,
_ => fib(n-1).await + fib(n-2).await}}The compiler helpfully tells us that:
error[E0733]: recursion in an `async fn` requires boxing --> src/main.rs:1:26 |1 | async fn fib(n : u32) -> u32 { | ^^^ recursive `async fn` | = note: a recursive `async fn` must be rewritten to return a boxed `dyn Future` = note: consider using the `async_recursion` crate: https://crates.io/crates/async_recursionThis crate provides an attribute macro to automatically convert an async function
to one returning a boxed Future.
use async_recursion::async_recursion;#[async_recursion]asyncfnfib(n:u32) -> u32{match n {0 | 1 => 1,
_ => fib(n-1).await + fib(n-2).await}}The returned Future has a Send bound to make sure it can be sent between threads.
If this is undesirable you can mark that the bound should be left out like so:
#[async_recursion(?Send)]asyncfnreturned_future_is_not_send(){// ...}The returned Future doesn't have a Sync bound as it is usually not required.
You can include a Sync bound as follows:
#[async_recursion(Sync)]asyncfnreturned_future_is_sync(){// ...}In detail:
#[async_recursion]modifies your function to return a boxedFuturewith aSendbound.#[async_recursion(?Send)]modifies your function to return a boxedFuturewithout aSendbound.#[async_recursion(Sync)]modifies your function to return a boxedFuturewith aSendandSyncbound.
Licensed under either of
- Apache License, Version 2.0 (LICENSE-APACHE or http://www.apache.org/licenses/LICENSE-2.0)
- MIT license (LICENSE-MIT or http://opensource.org/licenses/MIT)
at your option.