作为函数指针类型的异步函数:正确的类型定义是什么?
Async function as a function pointer type: what is the correct type definition?
我有一组定义为
的处理程序
async fn handler1(req: Request<'_>, state: web::Data<State>) -> Result<HttpResponse, Error<'_>> {
...
}
async fn handler2(req: Request<'_>, state: web::Data<State>) -> Result<HttpResponse, Error<'_>> {
...
}
我正在尝试的是 return 从匹配语句指向此类处理程序的指针:
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}`
所以我有两个问题:
MethodHandler
的正确类型定义是什么?
- 也许我完全是想在这里发明轮子,并且已经有一些库/通用模式可以用于我正在尝试做的事情?
正如评论中指出的那样,每个 async
块和函数 return 都是您无法命名的匿名类型。虽然即使可以,但它们中的每一个都是独一无二的,因此无论如何您都无法拥有一个 return 类型。您将需要装箱期货并使用动态调度。
最简单的解决方案是 futures
板条箱中的 BoxFuture
,它为您处理固定和生命周期。这将使您的类型定义
type MethodHandler = fn(req: Request<'_>, state: State)
-> BoxFuture<Result<HttpResponse, Error<'_>>>;
并且您需要使用 FutureExt::boxed
:
将 async
函数去糖化为 return 盒装未来
fn handler1(_req: Request<'_>, _state: State) -> BoxFuture<Result<HttpResponse, Error<'_>>> {
async move {
// Old function body
}.boxed()
}
您可以在 this playground.
找到一个编译示例,虽然缺少真实类型
我有一组定义为
的处理程序async fn handler1(req: Request<'_>, state: web::Data<State>) -> Result<HttpResponse, Error<'_>> {
...
}
async fn handler2(req: Request<'_>, state: web::Data<State>) -> Result<HttpResponse, Error<'_>> {
...
}
我正在尝试的是 return 从匹配语句指向此类处理程序的指针:
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}`
所以我有两个问题:
MethodHandler
的正确类型定义是什么?- 也许我完全是想在这里发明轮子,并且已经有一些库/通用模式可以用于我正在尝试做的事情?
正如评论中指出的那样,每个 async
块和函数 return 都是您无法命名的匿名类型。虽然即使可以,但它们中的每一个都是独一无二的,因此无论如何您都无法拥有一个 return 类型。您将需要装箱期货并使用动态调度。
最简单的解决方案是 futures
板条箱中的 BoxFuture
,它为您处理固定和生命周期。这将使您的类型定义
type MethodHandler = fn(req: Request<'_>, state: State)
-> BoxFuture<Result<HttpResponse, Error<'_>>>;
并且您需要使用 FutureExt::boxed
:
async
函数去糖化为 return 盒装未来
fn handler1(_req: Request<'_>, _state: State) -> BoxFuture<Result<HttpResponse, Error<'_>>> {
async move {
// Old function body
}.boxed()
}
您可以在 this playground.
找到一个编译示例,虽然缺少真实类型