如何在Rust中实现接收异步函数并返回异步函数的包装器?
Rust异步函数包装器的类型匹配问题
函数式编程中有个常见模式:接收一个函数,使用它后返回另一个通常签名相同的函数。Python里这个模式十分常见,甚至有专门的@装饰器语法。
我尝试在Rust中实现该模式,但在非简单场景下遇到了问题。
以下是可以正常运行的同步示例:
fn wrapper<T, V, F>(f: F) -> impl Fn(T) -> V where F: Fn(T) -> V { move |x| f(x) } fn my_func_1(x: u16) -> u16 { x * 2 } fn my_func_2(x: Vec<i32>) -> i32 { x.iter().sum() } fn main() { let res = wrapper(my_func_1)(42); let res = wrapper(my_func_2)(vec![1,2,3]); }
但在异步场景下情况变得复杂!我无法直接照搬同步实现的逻辑。不过我先实现了一个简单的可行方案:
use std::future::Future; fn wrapper<T, V, F, Fut>(f: F) -> impl Fn(T) -> Fut where F: Fn(T) -> Fut, Fut: Future<Output=V> { f } async fn my_func_1(x: u16) -> u16 { x * 2 } async fn my_func_2(x: Vec<i32>) -> i32 { x.iter().sum() } #[tokio::main] async fn main() { let res = wrapper(my_func_1)(42).await; println!("my_func_1: res = {:?}", res); let res = wrapper(my_func_2)(vec![1,2,3]).await; println!("my_func_2: res = {:?}", res); }
但和同步实现不同,我无法在异步包装器中创建新函数返回。比如以下代码:
fn wrapper<T, V, F, Fut>(f: F) -> impl Fn(T) -> Fut where F: Fn(T) -> Fut, Fut: Future<Output=V> { move |x| async { f(x) } }
会触发类型不匹配的错误:
error[E0308]: mismatched types --> src/main.rs:7:14 | 4 | fn wrapper<T, V, F, Fut>(f: F) -> impl Fn(T) -> Fut where | --- expected this type parameter ... 7 | move |x| async { f(x) } | ^^^^^^^^^^^^^^ expected type parameter `Fut`, found `async` block | = note: expected type parameter `Fut` found `async` block `{async block@src/main.rs:7:14: 7:28}` = help: every closure has a distinct type and so could not always match the caller-chosen type of parameter `Fut` For more information about this error, try `rustc --explain E0308`. error: could not compile `rust_test` (bin "rust_test") due to 1 previous error
请问有什么解决建议吗?
内容的提问来源于stack exchange,提问作者Nikolay S. Vasil'ev
相关产品推荐
相关产品推荐

