参照をコールバックとして受け取る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はより高い種類のポリモーフィズムをサポートしていないため、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.