How do I pass async closure as an argument of a function in Rust?
Asked Answered
T

1

1

I would like to implement an async function that takes async closure as the argument, so it must be called this way somewhere in the code:

my_func(async || { ... }).await;

What is the correct way to specify the data type of the argument?

I have tried this:

async fn my_func<F>(closure: F) where F: Fn() -> dyn std::future::Future<Output = ()> {
   closure.await;
   closure.await;
   closure.await;
}

But I got the error:

expected trait object `dyn Future`, found `async` closure body
Timisoara answered 23/7, 2024 at 13:8 Comment(0)
T
3

The trait bound for async closures is async Fn[Once/Mut](Args) -> ReturnType (although this may be changed):

#![feature(async_closure)]

async fn my_func<F>(closure: F)
where
    F: async Fn(),
{
    closure().await;
    closure().await;
    closure().await;
}

This translates into a bound on AsyncFn[Once/Mut], but you can't spell these traits directly.

Old-style bounds should also work, but they won't have the advantage of async closures, namely, the ability to use borrowed parameters and captures:

#![feature(async_closure)]

async fn my_func<F, Fut>(closure: F)
where
    F: Fn(&str) -> Fut,
    Fut: Future<Output = ()>,
{
    closure("").await;
    closure("").await;
    closure("").await;
}

// Won't compile:
my_func(async |s| { dbg!(s); }).await;
Tupiguarani answered 23/7, 2024 at 13:12 Comment(0)

© 2022 - 2025 — McMap. All rights reserved.