如何在Rust中将异步函数放入地图中?

乌孔·拉(Ukonn Ra)

为编写异步路由器时,我无法处理异步功能hyper

这段代码:

use std::collections::HashMap;
use std::future::Future;

type BoxedResult<T> = Result<T, Box<dyn std::error::Error + Send + Sync>>;
type CalcFn = Box<dyn Fn(i32, i32) -> dyn Future<Output = BoxedResult<i32>>>;

async fn add(a: i32, b: i32) -> BoxedResult<i32> {
    Ok(a + b)
}

async fn sub(a: i32, b: i32) -> BoxedResult<i32> {
    Ok(a - b)
}

fn main() {
    let mut map: HashMap<&str, CalcFn> = Default::default();
    map.insert("add", Box::new(add));
    map.insert("sub", Box::new(sub));

    println!("map size: {}", map.len());
}

生成以下编译器错误:

error[E0271]: type mismatch resolving `<fn(i32, i32) -> impl std::future::Future {add} as std::ops::FnOnce<(i32, i32)>>::Output == dyn std::future::Future<Output = std::result::Result<i32, std::boxed::Box<dyn std::error::Error + std::marker::Send + std::marker::Sync>>>`
  --> src/main.rs:17:23
   |
17 |     map.insert("add", Box::new(add));
   |                       ^^^^^^^^^^^^^ expected opaque type, found trait std::future::Future
   |
   = note: expected type `impl std::future::Future`
              found type `dyn std::future::Future<Output = std::result::Result<i32, std::boxed::Box<dyn std::error::Error + std::marker::Send + std::marker::Sync>>>`
   = note: required for the cast to the object type `dyn std::ops::Fn(i32, i32) -> dyn std::future::Future<Output = std::result::Result<i32, std::boxed::Box<dyn std::error::Error + std::marker::Send + std::marker::Sync>>>`

error[E0271]: type mismatch resolving `<fn(i32, i32) -> impl std::future::Future {sub} as std::ops::FnOnce<(i32, i32)>>::Output == dyn std::future::Future<Output = std::result::Result<i32, std::boxed::Box<dyn std::error::Error + std::marker::Send + std::marker::Sync>>>`
  --> src/main.rs:18:23
   |
18 |     map.insert("sub", Box::new(sub));
   |                       ^^^^^^^^^^^^^ expected opaque type, found trait std::future::Future
   |
   = note: expected type `impl std::future::Future`
              found type `dyn std::future::Future<Output = std::result::Result<i32, std::boxed::Box<dyn std::error::Error + std::marker::Send + std::marker::Sync>>>`
   = note: required for the cast to the object type `dyn std::ops::Fn(i32, i32) -> dyn std::future::Future<Output = std::result::Result<i32, std::boxed::Box<dyn std::error::Error + std::marker::Send + std::marker::Sync>>>`

impl Future之间似乎存在冲突dyn Future,但我不知道如何处理。

奥马尔·埃尔登(Omar Erden)

发生这种情况是因为impl Future它是具体的唯一类型,dyn Future而是抽象类型。HashMap期望抽象类型,因为它只能容纳单个类型的实例。

如果我们可以对异步函数的返回类型进行装箱,则可以将这些期货添加到中HashMap

首先,我们需要更改以下类型CalcFn

type CalcFn = Box<dyn Fn(i32, i32) -> Pin<Box<dyn Future<Output = i32>>>>;

然后可以做到这一点:

let mut map: HashMap<&str, CalcFn> = Default::default();
map.insert("add", Box::new(|a, b| Box::pin(add(a, b))));
map.insert("sub", Box::new(|a, b| Box::pin(sub(a, b))));

println!("map size: {}", map.len());

//map.get("add").unwrap()(2, 3).await

这个完整的示例简化FutureItem类型,使用i32的而不是一个Result请同时检查完整的代码

您也可以从期货箱子像使用类型LocalBoxFutureBoxFuture创建由FutureExt::boxedFutureExt::boxed_local分别的方法:

use futures::future::{FutureExt, LocalBoxFuture}; // 0.3.5
use std::collections::HashMap;

type BoxedResult<T> = Result<T, Box<dyn std::error::Error + Send + Sync>>;
type CalcFn = Box<dyn Fn(i32, i32) -> LocalBoxFuture<'static, BoxedResult<i32>>>;

async fn add(a: i32, b: i32) -> BoxedResult<i32> {
    Ok(a + b)
}

async fn sub(a: i32, b: i32) -> BoxedResult<i32> {
    Ok(a - b)
}

async fn example() {
    let mut map: HashMap<&str, CalcFn> = Default::default();
    map.insert("add", Box::new(|a, b| add(a, b).boxed()));
    map.insert("sub", Box::new(|a, b| sub(a, b).boxed()));

    println!("map size: {}", map.len());

    //map.get("add").unwrap()(2, 3).await
}

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章

如何在DynamoDB中将新的键值对放入地图中?(java)

如何在Rust中将'None'值传递给异步函数

如何在 Rust 中测试异步函数?

如何在pyspark中将2列汇总到地图中

如何在地图中将结构用作键

如何在Google地图中将圆圈拆分为扇区?

在地图中调用异步函数的最佳方法?

如何遍历复杂的JSON并放入地图中?

如何在JS中将变量放入Json Array函数中

如何在地图中存储函数(或lambda)然后执行?

如何在异步函数中将对象推入数组

如何在Python中将异步函数传递给线程目标?

如何在flutter(dart)中将异步函数声明为变量?

如何在React-Native中将任何大小的图像放入固定大小的视图中

如何在C#中将数组值放入列表视图中的特定列?

如何在Rust中将迭代器正确传递给函数

如何在Rust中将函数作为参数传递

如何在Rust中将匿名函数作为参数传递?

如何在Rust中将任意大小的矩阵传递给函数?

如何在Rust中将类型参数指定为函数参数?

C++ 如何将 lambda 放入地图中?

如何在 Grails 4 JSON 视图中将地图渲染为属性

如何在离子本机Google地图中将折线拟合到屏幕内部

如何在Erlang中将文本文件读取到地图中?

如何在Android Studio的Google地图中将标记添加到特定位置?

如何在 Java 中将自定义对象列表重新组合到地图中?

如何在动态编程中将递归值存储在我的地图中

如何在OpenCV中将文本放入边框?

如何在wpf中将图标放入环