Почему значение живет достаточно долго в цикле в функции, но не в прямом коде в tokio :: spawn? - PullRequest
1 голос
/ 28 октября 2019

У меня проблемы с пониманием перемещенных значений в цикле с использованием tokio: spawn в tokio 0.2. Я пытаюсь передать приемник однокадрового сигнала в функцию прослушивания, которая периодически проверяет его с таймаутом в цикле.

Странно, это работает, когда я использую отдельную функцию listen в tokio::spawn. Тем не менее, когда я копирую код из этой функции внутри замыкания tokio::spawn, он не компилирует жалобы на то, что значение перемещено в предыдущем цикле (что я понимаю). Итак, почему это работает в версии функции?

Вот пример для рабочей версии:

use std::time::Duration;
use tokio::{sync::oneshot, future::FutureExt, timer::delay_for};

pub async fn a() {
    let (stop_sender, mut stop_receiver) = oneshot::channel::<bool>();
    tokio::spawn(async move {
        listen(&mut stop_receiver).await;
    });
    delay_for(Duration::new(1,0)).await;
    stop_sender.send(true).unwrap();
}    

async fn listen(stop_receiver: &mut oneshot::Receiver<bool>) {
    loop {
        match stop_receiver.timeout(Duration::from_secs(1)).await {
            Ok(no_timeout) => match no_timeout {
                Ok(stop) =>
                    if stop {
                        println!("stop signal true received");
                        break;
                    },
                Err(_) => (), // don't stop
            },
            Err(_) => (), // timeout
        }
    }
}

#[tokio::main]
async fn main() {
    a().await;
    delay_for(Duration::new(2,0)).await;
}

Не работает следующее:

use std::time::Duration;
use tokio::{sync::oneshot, future::FutureExt, timer::delay_for};

pub async fn b() {
    let (stop_sender, mut stop_receiver) = oneshot::channel::<bool>();
    tokio::spawn(async move {
        loop {
            match stop_receiver.timeout(Duration::from_secs(1)).await {
                Ok(no_timeout) => match no_timeout {
                    Ok(stop) =>
                        if stop {
                            println!("stop signal true received");
                            break;
                        },
                    Err(_) => (), // don't stop
                },
                Err(_) => (), // timeout
            }
        }
    });
    delay_for(Duration::new(1,0)).await;
    stop_sender.send(true).unwrap();
}    

#[tokio::main]
async fn main() {
    b().await;
    delay_for(Duration::new(2,0)).await;
}

Когда я удаляю тайм-аут, он также не работает в версии функции (ошибка: перемещенное значение в предыдущей итерации цикла). Почему это так, то есть почему это вообще работает в версии функции с таймаутом? К сожалению, я не могу найти объяснение с предыдущими ответами на перемещенные значения в цикле. Может быть, кто-то может объяснить это. Спасибо!

...