Опция <Receiver>Перемещена в предыдущей итерации цикла - PullRequest
0 голосов
/ 05 марта 2019

Я порождаю поток, который делает некоторую работу.Иногда я хочу, чтобы эта нить умерла после завершения работы, иногда я хочу, чтобы она ждала, когда будет выполнено больше работы.Для этого я передаю Option<Receiver<T>>.Если Option<Receiver<T>> равно None поток должен умереть, иначе он должен ждать, чтобы получить больше работы.

fn foo(rx: Option<Receiver<usize>>) {
    thread::spawn(move || {
        loop {
            do_some_work();
            if let Some(r) = rx {
                match r.recv() {
                    Ok(x)  => {}
                    Err(_) => panic!("Oh no!"),
                }
            } else {
                break; //Die
            }
        }
    });
}

( ссылка на площадку )

Компиляторговорит:

error[E0382]: use of moved value
  --> src/lib.rs:10:25
   |
10 |             if let Some(r) = rx {
   |                         ^ value moved here, in previous iteration of loop
   |
   = note: move occurs because value has type `std::sync::mpsc::Receiver<usize>`, which does not implement the `Copy` trait

Однако, если Receiver не заключен в Option, все в порядке.

fn foo(rx: Receiver<usize>) {
    thread::spawn(move || {
        loop {
            do_some_work();
            match rx.recv() {
                Ok(x)  => {}
                Err(_) => panic!("Oh no!"),
            }
        }
    });
}

1 Ответ

0 голосов
/ 05 марта 2019

Когда вы пишете if let Some(r) = rx, вы потребляете rx, делая его недоступным для дальнейшего использования.

Вы можете использовать as_ref(), чтобы получить ссылку на внутренний объект, оставив rx пригодным для использования:

fn foo(rx: Option<Receiver<usize>>) {
    thread::spawn(move || {
        loop {
            do_some_work();
            if let Some(r) = rx.as_ref() {
                match r.recv() {
                    Ok(x) => {}
                    Err(_) => panic!("Oh no!"),
                }
            } else {
                break; //Die
            }
        }
    });
}

( ссылка на игровую площадку )

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