Как указать, что время жизни возвращаемого значения функции asyn c совпадает с параметром? - PullRequest
1 голос
/ 10 марта 2020

Мы можем сопоставить обычную функцию с нестати c параметром, например так:

fn processor(data: &i32) -> &i32 {
    data
}

fn process<'b>(data: &'b i32, processor: impl 'static + for<'a> Fn(&'a i32) -> &'a i32) -> &'b i32 {
    processor(data)
}

fn main() {
    let data = 1;
    println!("data: {}", process(&data, processor));
}

Поскольку асин c функции возвращают анонимное будущее, мы не можем указать, что время жизни анонимного будущего является совпадает с параметром:

use std::future::Future;

async fn processor(data: &i32) -> &i32 {
    data
}

async fn process<'b, F>(data: &'b i32, processor: impl 'static + Fn(&i32) -> F) -> &'b i32
where
    F: 'b + Future<Output = &'b i32>,
{
    processor(data).await
}

async fn _main() {
    let data = 1;
    println!("data: {}", process(&data, processor).await);
}

Компилятор будет жаловаться:

error[E0271]: type mismatch resolving `for<'r> <for<'_> fn(&i32) -> impl std::future::Future {processor} as std::ops::FnOnce<(&'r i32,)>>::Output == _`
  --> src/lib.rs:16:26
   |
7  | async fn process<'b, F>(data: &'b i32, processor: impl 'static + Fn(&i32) -> F) -> &'b i32
   |          -------                                                             - required by this bound in `process`
...
16 |     println!("data: {}", process(&data, processor).await);
   |                          ^^^^^^^ expected bound lifetime parameter, found concrete lifetime

Как мне его сопоставить?

1 Ответ

3 голосов
/ 10 марта 2020

Необходимо указать, что:

  1. закрытие принимает ссылку с тем же временем жизни, что и у параметра.
  2. возвращенное будущее возвращает ссылку с тем же временем жизни, что и у параметра .
  3. возвращаемое будущее захватывает ссылку с тем же временем жизни, что и у параметра.
async fn process<'b, F, Fut>(data: &'b i32, processor: F) -> &'b i32
where
    F: Fn(&'b i32) -> Fut,
    //     ^^ [1]
    F: 'static,
    Fut: Future<Output = &'b i32> + 'b,
    //                    ^^ [2]    ^^ [3]
{
    processor(data).await
}
...