async fn
返回实现Future
的匿名类型,因此,如果我们要将其用作回调,则需要将返回值转换为特征对象。
我试图编写一个函数来执行此操作,但是我遇到了一些终身问题。
async fn
将返回所有参数的生存期,因此回调的签名也需要。如何将生存期添加到回调的返回值?
use futures::future::{Future, LocalBoxFuture, FutureExt};
type Context = ();
type AsyncCb = Box<dyn for<'r> FnOnce(&'r Context)-> LocalBoxFuture<'r, ()>>;
fn normalize_async_cb<Fut: Future<Output=()>>(f: for<'r> fn(&'r Context) -> Fut ) -> AsyncCb
// how to add 'r for Fut? ^^^
{
let cb = move |ctx: &Context| {
f(ctx).boxed_local()
};
Box::new(cb)
}
答案 0 :(得分:1)
Rust不支持种类繁多的多态性,因此您需要向AsyncCb
类型添加寿命参数:
use futures::future::{Future, FutureExt, LocalBoxFuture};
type Context = ();
type AsyncCb<'r> = Box<dyn FnOnce(&'r Context) -> LocalBoxFuture<'r, ()> + 'r>;
fn normalize_async_cb<'r, Fut: Future<Output = ()> + 'r>(f: fn(&'r Context) -> Fut) -> AsyncCb {
let cb = move |ctx: &'r Context| f(ctx).boxed_local();
Box::new(cb)
}
另外,您可以通过返回Box
特征来避免使用impl
:
fn normalize_async_cb<'r, Fut: Future<Output = ()> + 'r>(
f: fn(&'r Context) -> Fut,
) -> impl FnOnce(&'r Context) -> LocalBoxFuture<'r, ()> {
let cb = move |ctx: &'r Context| f(ctx).boxed_local();
cb
}
(如果需要,呼叫者可以将Box::new(normalize_async_cb(…))
用作类型AsyncCb
。)