จะใช้ Rust async fn ที่ใช้การอ้างอิงเป็นการติดต่อกลับได้อย่างไร


10

async fnส่งคืนชนิดที่ไม่ระบุชื่อที่ใช้Futureดังนั้นหากเราต้องการใช้เป็นโทรกลับเราต้องแปลงค่าส่งคืนเป็นวัตถุลักษณะ

ฉันพยายามเขียนฟังก์ชั่นการทำเช่นนี้ แต่ฉันมีปัญหาตลอดชีวิต

async fnจะคืนค่าอายุการใช้งานของพารามิเตอร์ทั้งหมดดังนั้นลายเซ็นของการติดต่อกลับยังต้อง ฉันจะเพิ่มอายุการใช้งานในค่าส่งคืนของการโทรกลับได้อย่างไร

use futures::future::{Future, FutureExt, LocalBoxFuture};

type Context = ();
type AsyncCb = Box<dyn for<'r> FnOnce(&'r Context) -> LocalBoxFuture<'r, ()>>;

fn normalize_async_cb<Fut: Future<Output = ()>>(f: for<'r> fn(&'r Context) -> Fut) -> AsyncCb
//                                                    how to add 'r for Fut?  ^^^
{
    let cb = move |ctx: &Context| f(ctx).boxed_local();
    Box::new(cb)
}

ทำไมอินพุตถึงnormalize_async_cbตัวชี้ฟังก์ชัน?
Coder-256

นอกจากนี้คุณหมายถึงอะไรโดย "โทรกลับ"? คุณสามารถให้ตัวอย่างที่แสดงว่าคุณต้องการโทรกลับประเภทนี้ได้ที่ไหน
Coder-256

คำตอบ:


1

Rust ไม่รองรับ polymorphism ที่สูงกว่าดังนั้นคุณต้องเพิ่มพารามิเตอร์อายุการใช้งานลงในAsyncCbประเภท:

use futures::future::{Future, FutureExt, LocalBoxFuture};

type Context = ();
type AsyncCb<'r> = Box<dyn FnOnce(&'r Context) -> LocalBoxFuture<'r, ()> + 'r>;

fn normalize_async_cb<'r, Fut: Future<Output = ()> + 'r>(f: fn(&'r Context) -> Fut) -> AsyncCb {
    let cb = move |ctx: &'r Context| f(ctx).boxed_local();
    Box::new(cb)
}

โดยทั่วไปคุณสามารถหลีกเลี่ยงได้Boxโดยการส่งกลับimplลักษณะ:

fn normalize_async_cb<'r, Fut: Future<Output = ()> + 'r>(
    f: fn(&'r Context) -> Fut,
) -> impl FnOnce(&'r Context) -> LocalBoxFuture<'r, ()> {
    let cb = move |ctx: &'r Context| f(ctx).boxed_local();
    cb
}

(ผู้โทรสามารถใช้Box::new(normalize_async_cb(…))เป็นประเภทได้AsyncCbหากต้องการ)

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.