Как я могу продлить время жизни структуры, чтобы я мог вызвать tokio :: run с ней? - PullRequest
0 голосов
/ 30 октября 2018

У меня есть функция, которая работает:

extern crate tokio;

use std::time::{Duration, Instant};
use tokio::prelude::*;
use tokio::timer::Interval;

fn run(label: String) -> impl Future<Item = (), Error = ()> {
    Interval::new(Instant::now(), Duration::from_millis(1000))
        .for_each(move |instant| {
            println!("fire; instant={:?}, label={:?}", instant, label);
            Ok(())
        })
        .map_err(|e| panic!("interval errored; err={:?}", e))
}

fn main() {
    tokio::run(run("Hello".to_string()));
}

площадка

Я хотел бы создать структуру, которая будет содержать некоторые параметры (label) в этом случае с помощью метода run, который будет использовать параметры:

extern crate tokio;

use std::time::{Duration, Instant};
use tokio::prelude::*;
use tokio::timer::Interval;

struct Ir {
    label: String,
}

impl Ir {
    fn new(label: String) -> Ir {
        Ir { label }
    }

    fn run(&self) -> impl Future<Item = (), Error = ()> + '_ {
        Interval::new(Instant::now(), Duration::from_millis(1000))
            .for_each(move |instant| {
                println!("fire; instant={:?}, label={:?}", instant, self.label);
                Ok(())
            })
            .map_err(|e| panic!("interval errored; err={:?}", e))
    }
}

fn main() {
    let ir = Ir::new("Hello".to_string());
    tokio::run(ir.run());
}

детская площадка

Что я получаю:

error[E0597]: `ir` does not live long enough
  --> src/main.rs:28:16
   |
28 |     tokio::run(ir.run());
   |                ^^ borrowed value does not live long enough
29 | }
   | - borrowed value only lives until here
   |
   = note: borrowed value must be valid for the static lifetime...

Я прочитал «Расширенные времена жизни» и «Проверка ссылок со временем жизни» из «Rust by Example», но я все еще не понимаю, как это исправить.
Почему ir не живет достаточно долго?
Я создал его в той же области, где я пытаюсь вызвать ir.run(), поэтому я предположил бы, что он останется.

1 Ответ

0 голосов
/ 30 октября 2018

Если переписать:

tokio::run(ir.run());

как:

tokio::run(Ir::run(&ir))

Ошибка становится немного понятнее:

error[E0597]: `ir` does not live long enough
  --> src/main.rs:28:24
   |
28 |    tokio::run(Ir::run(&ir));
   |                        ^^ borrowed value does not live long enough
29 | }
   | - borrowed value only lives until here
   |
   = note: borrowed value must be valid for the static lifetime...

Поскольку tokio::run требует 'static времени жизни для будущего:

pub fn run<F>(future: F) 
where
    F: Future<Item = (), Error = ()> + Send + 'static, 

Чтобы избежать проблем со временем жизни, рассмотрите использование значения Ir:

fn run(self) -> impl Future<Item = (), Error = ()>  {
    Interval::new(Instant::now(), Duration::from_millis(1000))
        .for_each(move |instant| {
            println!("fire; instant={:?}, label={:?}", instant, self.label);
            Ok(())
        })
        .map_err(|e| panic!("interval errored; err={:?}", e))
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...