Geri çağrı olarak başvuru alan bir Rust async fn nasıl kullanılır?


10

async fnuygulayan anonim bir tür döndürür Future; bu nedenle, geri arama olarak kullanmak istiyorsak, dönüş değerini bir özellik nesnesine dönüştürmemiz gerekir.

Bunu yapmak için bir işlev yazmaya çalıştım, ancak bazı yaşam boyu problemlerim vardı.

async fntüm parametrelerin ömrünü döndürür, bu nedenle geri arama imzasının da olması gerekir. Ömrünü geri aramanın dönüş değerine nasıl ekleyebilirim?

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

Neden normalize_async_cbbir işlev işaretçisi girdisi ?
Coder-256

Ayrıca, "geri arama" ile ne demek istiyorsun? Bu tür geri aramaya nerede ihtiyaç duyacağınızı gösteren bir örnek verebilir misiniz?
Coder-256

Yanıtlar:


1

Rust, yüksek tür polimorfizmi desteklemediğinden, türe bir ömür boyu parametre eklemeniz gerekir 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)
}

Ek olarak, bir özellik Boxdöndürerek aşağıdakilerden kaçınabilirsiniz 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
}

(Arayan daha sonra istenirse Box::new(normalize_async_cb(…))tür olarak kullanabilir AsyncCb.)

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.