rust - 作为函数指针类型 : what is the correct type definition? 的异步函数

标签 rust function-pointers

我有一组定义为的处理程序

async fn handler1(req: Request<'_>, state: web::Data<State>) -> Result<HttpResponse, Error<'_>> {
    ...
}
async fn handler2(req: Request<'_>, state: web::Data<State>) -> Result<HttpResponse, Error<'_>> {
    ...
}

我正在尝试的是从匹配语句返回指向此类处理程序的指针:

type MethodHandler = fn(req: Request<'_>, state: web::Data<State>) -> Result<HttpResponse, Error<'_>>;

fn select_handler(method: &str) -> Option<MethodHandler> {
    match method {
        "handler1" => Some(handler1),
        "handler2" => Some(handler2),
        _ => None
    }
}

由于处理程序的异步性质,它运行得不是很好:

error[E0308]: mismatched types
    --> src/handlers.rs:384:34
     |
1084 |         "handler1" => Some(handler1),
     |                                  ^^^^^^^^^^^^^^^^ expected enum `std::result::Result`, found opaque type
     |
     = note: expected fn pointer `for<'r> fn(handlers::Request<'r>, actix_web::web::Data<_>) -> std::result::Result<HttpResponse, handlers::Error<'r>>`
                   found fn item `for<'_> fn(handlers::Request<'_>, actix_web::web::Data<_>) -> impl futures_util::Future {handler1}`

error[E0308]: mismatched types
    --> src/handlers.rs:385:38
     |
1085 |         "handler1" => Some(handler1),
     |                                      ^^^^^^^^^^^^^^^^^^^^ expected enum `std::result::Result`, found opaque type
     |
     = note: expected fn pointer `for<'r> fn(handlers::Request<'r>, actix_web::web::Data<_>) -> std::result::Result<HttpResponse, handlers::Error<'r>>`
                   found fn item `for<'_> fn(handlers::Request<'_>, actix_web::web::Data<_>) -> impl futures_util::Future {handler2}`

所以我有两个问题:

  1. MethodHandler 的正确类型定义是什么?
  2. 也许我完全是想在这里发明轮子,并且已经有一些库/通用模式可以用于我正在尝试做的事情?

最佳答案

正如评论中所指出的,每个 async block 和函数都会返回一个您无法命名的匿名类型。尽管即使可以,它们中的每一个都是唯一的,因此无论如何您都无法拥有单一的返回类型。您将需要装箱 future 并使用动态调度。

最简单的解决方案是 BoxFuture来自 futures crate ,它为您处理固定和生命周期。这将使您的类型定义

type MethodHandler = fn(req: Request<'_>, state: State)
                -> BoxFuture<Result<HttpResponse, Error<'_>>>;

并且您需要通过使用 FutureExt::boxed 对您的 async 函数进行去糖处理以返回一个盒装的 future。 :

fn handler1(_req: Request<'_>, _state: State) -> BoxFuture<Result<HttpResponse, Error<'_>>> {
    async move {
        // Old function body
    }.boxed()
}

您可以在 this playground 找到一个编译示例,尽管缺少实际类型。 .

关于rust - 作为函数指针类型 : what is the correct type definition? 的异步函数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/68928795/

相关文章:

c++ - C++ 的 XCode 错误 "Undefined symbols for architecture x86_64"

c# - c#中的委托(delegate)和c++中的函数指针有什么区别?

rust - Box<dyn Trait> 如何 self 解构?

rust - 无需代码重复即可在单项测试中多次 panic

rust - 如何将JSON模式作为数据传递给Actix Web?

c++ - C++ 中的函数指针和未知数量的参数

c++ - 标准运算符的函数指针

c - 如何在 C 的结构中使用函数指针?

rust - 循环中的Rust所有权

multithreading - 使用 channel 和线程时我要等待或加入什么?