Rust: пожизненная анонимная функция - PullRequest
2 голосов
/ 01 февраля 2020

Я пытаюсь смоделировать асинхронное c выполнение с помощью функции spawn, но мне не удается скомпилировать фрагмент кода ниже.

use std::thread::{spawn, JoinHandle};

fn main() {
    let data  = vec![String::from("some data"), String::from("some more data")];

    let doer = Doer{f: |x| {return x + " hello"} };

    let results: Vec<JoinHandle<String>> = data.iter()
        .map(|x| doer.apply_async(x.to_owned()))
        .collect();

    results.iter().for_each(|x| println!("{}", x.join().unwrap()));
}

struct Doer {
    f: fn(xs: String) -> String
}

impl Doer {
    fn apply(&self, datum: String) -> String {
        let f = &self.f;
        return f(datum);
    }

    fn apply_async(&self, datum: String) -> JoinHandle<String> {
        return spawn(move|| self.apply(datum));
    }
}

У меня есть ошибка, подобная этой first, the lifetime cannot outlive the anonymous lifetime #1 defined on the method body at 25:5...

Я не уверен, что понимаю, какое время жизни переживает анонимное время жизни. Есть идеи?

1 Ответ

1 голос
/ 01 февраля 2020

apply_async - метод, который принимает &self. Это означает, что self является ссылкой, которая гарантированно будет действовать только в течение вызова до apply_async. Закрытие move || self.apply(datum) захватывает self, время жизни и все, что означает, что оно не 'static. Вот почему вы не можете вызвать spawn для него.

Если Doer реализует Clone, один из способов решить эту проблему - сделать клон из *self и move в закрытие.

    fn apply_async(&self, datum: String) -> JoinHandle<String> {
        let s = self.clone();
        return spawn(move || s.apply(datum));
    }

Если вы не хотите клонировать целое Doer, вы можете скопировать только необходимые части и переопределить apply внутри apply_async, например:

    fn apply_async(&self, datum: String) -> JoinHandle<String> {
        let f = self.f;
        return spawn(move|| f(datum));
    }
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...