我正在嘗試創建一個通用函式,該函式具有包裝異步閉包的令人印象深刻的目標。因此,出于所有意圖和目的,它將閉包視為一個黑盒,并根據傳入的閉包的回傳值在之前和之后簡單地運行一些設定邏輯。
這是迄今為止我整理的一個 MRE 示例代碼。我也在Rust 操場上對其進行了測驗。
use std::future::Future;
use std::pin::Pin;
#[derive(Default)]
struct MyEvent {}
#[derive(Default)]
struct MyContext {
pub fn_name: String,
}
pub struct HelpAnError {}
#[tokio::main]
async fn main() {
let my_age: u8 = 29;
let doing_work_hard = move |event: MyEvent, ctx: MyContext| async move {
println!("I'm working hard, i promise!");
println!("Ma i'm already {} yrs old!", my_age);
Ok::<_, HelpAnError>(())
};
let doing_chores_hard = lets_wrap_da_closure(doing_work_hard);
// does all the chores that Ma assigned to me
let _ = doing_chores_hard(Default::default(), Default::default()).await;
}
fn lets_wrap_da_closure<
C: Fn(MyEvent, MyContext) -> F,
F: Future<Output = Result<(), HelpAnError>>,
>(
do_work_hard: C,
) -> fn(MyEvent, MyContext) -> Pin<Box<dyn Future<Output = Result<(), HelpAnError>>>> {
move |event: MyEvent, ctx: MyContext| {
Box::pin(async move {
println!("I'm doin my chores Ma, I promise!");
// **help** - if I uncomment this it fails!
// do_work_hard(event, ctx).await;
println!("Yay! The chores are now complit.");
Ok(())
})
}
}
我將不勝感激有關如何使其與 rust 編譯器一起作業的任何幫助或指示,這對我來說似乎不太友好。我覺得我已經掙扎了幾個小時,但不夠聰明或不夠熟練,不知道如何滿足編譯器規則。
我還檢查了從 Rust 中的函式回傳異步函式,并獲得了相應使用的提示Box::pin。但是,我在為我的特定用例實作它時遇到了麻煩,即我想創建一個通用函式來包裝一個Future特別回傳 a 的可呼叫物件。謝謝,如果我需要澄清任何事情,請告訴我。
更新:感謝@Jakub 的幫助。以下是我修改后的(作業)代碼:
use std::future::Future;
use std::pin::Pin;
#[derive(Default)]
struct MyEvent {}
#[derive(Default)]
struct MyContext {
pub fn_name: String,
}
#[derive(Debug)]
pub struct HelpAnError {}
#[tokio::main]
async fn main() {
let my_age: u8 = 29;
let doing_work_hard = move |event: MyEvent, ctx: MyContext| async move {
println!("I'm working hard, i promise!");
println!("Ma i'm already {} yrs old!", my_age);
Ok::<_, HelpAnError>(())
};
let doing_chores_hard = lets_wrap_da_closure(doing_work_hard);
// does all the chores that Ma assigned to me
let _ = doing_chores_hard(Default::default(), Default::default()).await;
}
fn lets_wrap_da_closure<
'a,
C: Fn(A1, A2) -> F,
A1,
A2,
E: std::fmt::Debug,
F: Future<Output = Result<(), E>> 'a,
>(
do_work_hard: C,
) -> impl Fn(A1, A2) -> Pin<Box<dyn Future<Output = Result<(), E>> 'a>> {
move |event: A1, ctx: A2| {
let fut = do_work_hard(event, ctx);
Box::pin(async move {
println!("I'm doin my chores Ma, I promise!");
// it WORKS! wow, amazing ~
match fut.await {
Ok(_) => println!("All systems are a GO!"),
Err(e) => println!("I ran into issue doing my chores: {:?}", e),
};
println!("Yay! The chores are now complit.");
Ok(())
})
}
}
旁注:將它包裝dyn Future<Output = Result<(), HelpAnError>>成一個通用的或者只是重用它會很好F,但在這一點上,我很高興能夠讓它作業:-)
uj5u.com熱心網友回復:
use std::future::Future;
use std::pin::Pin;
#[derive(Default)]
struct MyEvent {}
#[derive(Default)]
struct MyContext {
pub fn_name: String,
}
pub struct HelpAnError {}
#[tokio::main]
async fn main() {
let my_age: u8 = 29;
let doing_work_hard = move |event: MyEvent, ctx: MyContext| async move {
println!("I'm working hard, i promise!");
println!("Ma i'm already {} yrs old!", my_age);
Ok::<_, HelpAnError>(())
};
let doing_chores_hard = lets_wrap_da_closure(doing_work_hard);
// does all the chores that Ma assigned to me
let _ = doing_chores_hard(Default::default(), Default::default()).await;
}
fn lets_wrap_da_closure<
C: Fn(MyEvent, MyContext) -> F 'static,
F: Future<Output = Result<(), HelpAnError>> 'static,
>(
do_work_hard: C,
) -> impl Fn(MyEvent, MyContext) -> Pin<Box<dyn Future<Output = Result<(), HelpAnError>>>> {
move |event: MyEvent, ctx: MyContext| {
// this is the only way i can satisfy the compiler, do not worry,
// future will get executed only upon await and this call is just
// creating the future we are passing
let fut = do_work_hard(event, ctx);
Box::pin(async move {
println!("I'm doin my chores Ma, I promise!");
// **help** - if I uncomment this it fails!
drop(fut.await);
println!("Yay! The chores are now complit.");
Ok(())
})
}
}
轉載請註明出處,本文鏈接:https://www.uj5u.com/gongcheng/451756.html
