背景

rust 1.67.1 (d5a82bbd2 2023-02-07) 版本测试失常

应用rusthashmap存储i32key, 函数作为value, 当查问某个key如果存在具体的函数则调用

反对异步函数存储与调用

次要办法

  • 如果类型不同,则须要包一层Box,把存储的内容放到堆内存上,保障编译器能够失常计算内存大小,次要是针对存储在栈上的内存大小
  • 如果是异步办法,因为异步函数没有申明Unpin,所以须要包一层Pin,应用Box::pin实现,次要是保障异步函数运行的时候不会挪动future

同步函数,雷同参数,雷同返回值的实现

use std::collections::HashMap;fn first(value: i32) -> i32 {    println!("{value} in sync first");    value}fn second(value: i32) -> i32 {    println!("{value} in sync second");    value}type HashMapFun = HashMap<i32, Box<dyn Fn(i32) -> i32>>;fn main() {    let mut map: HashMapFun= HashMap::new();    map.insert(1, Box::new(first));    map.insert(2, Box::new(second));    for v in 0..4 {        map.get(&v).and_then(|f| Some(f(v)));    }}

同步函数-雷同参数-不同返回值的实现

  • 因为返回的值不同,所以每个存储的函数返回值都被蕴含了一层Box
  • hashmap插入函数的时候编译器冀望的是一个trait object,如果间接传递first或者second会产生报错,能够只有闭包解决
use std::collections::HashMap;use std::fmt::Display;fn first(value: i32) -> Box<impl Display> {    println!("{value} in sync first");    Box::new(value)}fn second(value: i32) -> Box<String> {    println!("{value} in sync second");    Box::new(format!("-----{value}"))}type HashMapFun = HashMap<i32, Box<dyn Fn(i32) -> Box<dyn Display>>>;fn main() {    let mut map: HashMapFun = HashMap::new();    map.insert(1, Box::new(|x| first(x)));    map.insert(2, Box::new(|x| second(x)));    for v in 0..4 {        map.get(&v).and_then(|f| Some(f(v)));    }}

异步函数-雷同参数-雷同返回值的实现

use std::collections::HashMap;use std::future::Future;use std::pin::Pin;async fn third(value: i32) -> i32 {    println!("{value} in async third");    tokio::time::sleep(std::time::Duration::from_secs(1)).await;    value}async fn fourth(value: i32) -> i32 {    println!("{value} in async fourth");    tokio::time::sleep(std::time::Duration::from_secs(1)).await;    value}type HashMapAsyncFun = HashMap<i32, Box<dyn Fn(i32) -> Pin<Box<dyn Future<Output = i32>>>>>;#[tokio::main]async fn main() {    let mut async_map: HashMapAsyncFun  =        HashMap::new();    async_map.insert(3, Box::new(|x| Box::pin(third(x))));    async_map.insert(4, Box::new(|x| Box::pin(fourth(x))));    for v in 0..5 {        if let Some(f) = async_map.get(&v) {            f(v).await;        }    }}

参考浏览

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

Cannot use "impl Future" to store async function in a vector