gpt4 book ai didi

rust - 如何使用将引用作为回调的 Rust 异步 fn?

转载 作者:行者123 更新时间:2023-12-03 11:23:26 24 4
gpt4 key购买 nike

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)
}

最佳答案

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。)

关于rust - 如何使用将引用作为回调的 Rust 异步 fn?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58891121/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com