Rust小技巧 - 把异步函数放进vector当中

1 场景说明

有些时候,我们希望将将异步函数放到vector当中,或者说是注册进vector当中,然后在某个地方遍历这个vector来实现对已经注册了的异步函数的调用。

Cargo.toml中需要的依赖

[dependencies]
tokio = { version = "1", features = ["full"] }

2 解决方案

因为rust需要知道如何分配内存,而不同的异步函数返回结果会不同,所以这里要用到BoxPin

2.1 无借用参数

当异步函数的输入参数重没有借用时,也就不涉及到生命周期的问题,这时可以参考下面这个例子来实现。

use std::{future::Future, pin::Pin};

type PinFutureObjWithoutLife<Output> = Pin<Box<dyn Future<Output = Output>>>;
type ItemWithoutLife = Box<dyn Fn(usize) -> PinFutureObjWithoutLife<()>>;

async fn collection_of_asyncs_without_ref() {
    let vec: Vec<ItemWithoutLife> = vec![
        Box::new(|num| Box::pin(func1_without_ref(num))),
        Box::new(|num| Box::pin(func2_without_ref(num))),
        Box::new(|num| Box::pin(func1_without_ref(num))),
        Box::new(|num| Box::pin(func2_without_ref(num))),
    ];

    for (idx, f) in vec.iter().enumerate() {
        f(idx).await
    }
}

async fn func1_without_ref(num: usize) -> ()
{
    println!("func1_without_ref-{}", num);
}

async fn func2_without_ref(num: usize) -> ()
{
    println!("func2_without_ref-{}", num);
}

#[tokio::main]
async fn main(){
    collection_of_asyncs_without_ref().await;
}

2.2 有借用参数

当输入参数重带了借用参数的话,就有生命周期的问题了,rust需要我们指明生命周期,可以参考下面这个例子来实现。

use std::{future::Future, pin::Pin};

type PinFutureObjWithLife<'a, T> = Pin<Box<dyn Future<Output = T> + 'a>>;
type ItemWithLife = Box<dyn for<'a> Fn(&'a mut usize) -> PinFutureObjWithLife<'a, ()>>;

async fn collection_of_asyncs_with_ref() {
    let mut vec = Vec::<ItemWithLife>::new();
    vec.push(Box::new(|num| Box::pin(func1_with_ref(num))));
    vec.push(Box::new(|num| Box::pin(func2_with_ref(num))));
    vec.push(Box::new(|num| Box::pin(func1_with_ref(num))));
    vec.push(Box::new(|num| Box::pin(func2_with_ref(num))));

    for (mut idx, f) in vec.iter().enumerate() {
        f(&mut idx).await
    }
}

async fn func1_with_ref(num: &mut usize) -> ()
{
    println!("func1_with_ref-{}", num);
}

async fn func2_with_ref(num: &mut usize) {
    println!("func2_with_ref-{}", num);
}

#[tokio::main]
async fn main(){
    collection_of_asyncs_with_ref().await;
}

参考资料

[1] https://stackoverflow.com/questions/58354633/cannot-use-impl-future-to-store-async-function-in-a-vector

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

七元权

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值