Как лучше всего решить проблему «Невозможно вернуть значение, ссылающееся на параметр функции» с помощью функции asyn c? - PullRequest
1 голос
/ 07 мая 2020

Я борюсь с проблемой заимствования:

async fn bugger(_foo: &String) {}

fn main() {
    Some("".to_string()).map(|foo| bugger(&foo));
}

Ошибка:

error[E0515]: cannot return value referencing function parameter `foo`
 --> src/main.rs:4:36
  |
4 |     Some("".to_string()).map(|foo| bugger(&foo));
  |                                    ^^^^^^^----^
  |                                    |      |
  |                                    |      `foo` is borrowed here
  |                                    returns a value referencing data owned by the current function

Думаю, проблема в том, что будущее, возвращаемое bugger(), хранит &String ссылку в своем конечном автомате.

Поскольку переменная foo принадлежит в закрытии map(), обходной путь будет:

async fn bugger(_foo: &String) {}

async fn workaround(_foo: String) {
    bugger(&_foo).await
}

fn main() {
    Some("".to_string()).map(|foo| workaround(foo));
}

Я считаю это неэлегантным, потому что компилятор знает, что foo принадлежит и используется только при вызове bugger, поэтому функция workaround() выглядит как шаблон, которого можно избежать.

Предполагая, что я не могу изменить подпись bugger() (потому что она определена в другом crate), есть ли лучший способ сделать это?

Примечание: использование .as_ref().map() также будет работать для этого надуманного примера, но мне хотелось бы решение, которое работает и в более сложных случаях (например, map() в середине итератора или потока).

РЕДАКТИРОВАТЬ: вот более реалистичный c пример, чтобы прояснить вариант использования.

use futures::stream::{self, StreamExt};

async fn bugger(_foo: & String) -> u8 { 0u8 }

fn main() {
    let vec = vec!["".to_string()];

    let _stream = stream::iter(vec)
        // Apply async function
        .map(|foo| bugger(&foo))
        // Process 10 items "in parallel"
        .buffer_unordered(10)
        // Possibly do more stuff with the stream here
        // [...]
        // .collect().await
        ;
}

В основном я хочу применить сторонняя функция asyn c (принимающая ссылку) в поток.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...