首页 > 解决方案 > 在地图中存储异步回调

问题描述

我试图将多个异步回调存储在一个哈希映射中,稍后我会对其进行迭代。这是我最接近让它工作的尝试,但是,由于回调的生命周期,我收到了编译错误。

use std::boxed::Box;
use std::collections::HashMap;
use std::future::Future;
use std::pin::Pin;

type AsyncCallback = Box<dyn Fn() -> Pin<Box<dyn Future<Output = ()>>>>;

#[derive(Default)]
pub struct CallbackMap {
    callbacks: HashMap<&'static str, AsyncCallback>,
}

impl CallbackMap {
    pub fn add<C, F>(&mut self, name: &'static str, callback: C)
    where
        C: Fn() -> F,
        C: 'static,
        F: Future<Output = ()> + 'static,
    {
        self.callbacks
            .insert(name, Box::new(|| Box::pin(callback())));
    }

    pub async fn execute(&self) {
        for (_key, value) in &self.callbacks {
            value().await;
        }
    }
}

async fn async_callback() {
    println!("Callback 2");
}

fn main() {
    let mut callbacks = CallbackMap::default();

    callbacks.add("test1", || async {
        println!("Callback 1");
    });

    callbacks.add("test2", async_callback);

    callbacks.execute();
}

这是我得到的错误:

error[E0597]: `callback` does not live long enough
  --> src/main.rs:21:48
   |
21 |             .insert(name, Box::new(|| Box::pin(callback())));
   |                           ---------------------^^^^^^^^----
   |                           |        |           |
   |                           |        |           borrowed value does not live long enough
   |                           |        value captured here
   |                           cast requires that `callback` is borrowed for `'static`
22 |     }
   |     - `callback` dropped here while still borrowed

标签: rust

解决方案


使用move关键字移动 callback到闭包中:

self.callbacks
    .insert(name, Box::new(move || Box::pin(callback())));
                        // ^^^^

推荐阅读