Bagaimana cara menggunakan Rust async fn yang menggunakan referensi sebagai panggilan balik?

10

async fnmengembalikan tipe anonim yang mengimplementasikan Future, jadi jika kita ingin menggunakannya sebagai panggilan balik, kita perlu mengonversi nilai kembali ke objek sifat.

Saya mencoba menulis fungsi untuk melakukan ini, tetapi saya memiliki beberapa masalah seumur hidup.

async fnakan mengembalikan seumur hidup semua parameter, sehingga tanda tangan panggilan balik juga perlu. Bagaimana saya bisa menambahkan masa pakai ke nilai balik dari callback?

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)
}
s97712
sumber
Mengapa input ke normalize_async_cbpointer fungsi?
Coder-256
Juga, apa yang Anda maksud dengan "panggilan balik"? Bisakah Anda memberikan contoh yang menunjukkan di mana Anda akan membutuhkan jenis panggilan balik ini?
Coder-256

Jawaban:

1

Karat tidak mendukung polimorfisme jenis yang lebih tinggi, jadi Anda perlu menambahkan parameter seumur hidup ke AsyncCbjenis:

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)
}

Secara tradisional, Anda dapat menghindari Boxdengan mengembalikan implsifat:

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
}

(Penelepon kemudian dapat digunakan Box::new(normalize_async_cb(…))sebagai tipe AsyncCbjika diinginkan.)

Anders Kaseorg
sumber