Làm cách nào để sử dụng fn Rust async lấy tham chiếu làm cuộc gọi lại?


10

async fntrả về một kiểu ẩn danh thực hiện Future, vì vậy nếu chúng ta muốn sử dụng nó như một cuộc gọi lại, chúng ta cần chuyển đổi giá trị trả về thành một đối tượng đặc điểm.

Tôi đã cố gắng viết một chức năng để làm điều này, nhưng tôi đã có một số vấn đề suốt đời.

async fnsẽ trả về thời gian tồn tại của tất cả các tham số, vì vậy chữ ký gọi lại cũng cần phải có. Làm cách nào tôi có thể thêm thời gian tồn tại vào giá trị trả về của cuộc gọi lại?

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

Tại sao đầu vào của normalize_async_cbmột con trỏ hàm?
Coder-256

Ngoài ra, ý của bạn là "gọi lại" là gì? Bạn có thể cung cấp một ví dụ cho thấy nơi bạn sẽ cần loại gọi lại này?
Coder-256

Câu trả lời:


1

Rust không hỗ trợ đa hình loại cao hơn, vì vậy bạn cần thêm một tham số trọn đời cho AsyncCbloại:

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

Thông thường, bạn có thể tránh một Boxbằng cách trả lại implđặc điểm:

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
}

(Người gọi sau đó có thể sử dụng Box::new(normalize_async_cb(…))như loại AsyncCbnếu muốn.)

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.