async fn返回一个实现 的匿名类型Future,因此如果我们想将它用作回调,我们需要将返回值转换为一个 trait 对象。
我试图编写一个函数来做到这一点,但我遇到了一些终身问题。
async fn将返回所有参数的生命周期,因此回调的签名也需要。如何将生命周期添加到回调的返回值中?
use futures::future::{Future, FutureExt, LocalBoxFuture};
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)
}
Run Code Online (Sandbox Code Playgroud)
Rust 不支持更高种类的多态性,因此您需要向类型添加生命周期参数AsyncCb:
use futures::future::{Future, FutureExt, LocalBoxFuture};\n\ntype Context = ();\ntype AsyncCb<\'r> = Box<dyn FnOnce(&\'r Context) -> LocalBoxFuture<\'r, ()> + \'r>;\n\nfn normalize_async_cb<\'r, Fut: Future<Output = ()> + \'r>(f: fn(&\'r Context) -> Fut) -> AsyncCb {\n let cb = move |ctx: &\'r Context| f(ctx).boxed_local();\n Box::new(cb)\n}\nRun Code Online (Sandbox Code Playgroud)\n\n此外,您可以Box通过返回impl特征来避免:
fn normalize_async_cb<\'r, Fut: Future<Output = ()> + \'r>(\n f: fn(&\'r Context) -> Fut,\n) -> impl FnOnce(&\'r Context) -> LocalBoxFuture<\'r, ()> {\n let cb = move |ctx: &\'r Context| f(ctx).boxed_local();\n cb\n}\nRun Code Online (Sandbox Code Playgroud)\n\n(如果需要,调用者可以使用Box::new(normalize_async_cb(\xe2\x80\xa6))as 类型AsyncCb。)
| 归档时间: |
|
| 查看次数: |
1692 次 |
| 最近记录: |