如何使用将引用作为回调的Rust异步fn? [英] How to use a Rust async fn that takes a reference as a callback?

查看:102
本文介绍了如何使用将引用作为回调的Rust异步fn?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

async fn返回实现Future的匿名类型,因此,如果我们要将其用作回调,则需要将返回值转换为trait对象.

async fn returns an anonymous type that implements Future, so if we want to use it as a callback, we need to convert the return value to a trait object.

我试图编写一个函数来执行此操作,但是我遇到了一些终身问题.

I tried to write an function to do this, but I had some lifetime problems.

async fn将返回所有参数的生存期,因此回调的签名也需要.如何将生存期添加到回调的返回值?

async fn will return lifetime of all parameters, so the signature of callback also needs to. How can I add the lifetime to the return value of the callback?

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类型添加一个生命周期参数:

Rust does not support higher-kinded polymorphism, so you need to add a lifetime parameter to the AsyncCb type:

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

另外,您可以通过返回impl性状来避免Box:

Aditionally, you can avoid a Box by returning impl trait:

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

(The caller can then use Box::new(normalize_async_cb(…)) as type AsyncCb if desired.)

这篇关于如何使用将引用作为回调的Rust异步fn?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆