Option<Receiver> Moved in Previous Loop Iteration

落花浮王杯 提交于 2019-12-25 02:59:11

问题


I'm spawning a thread that does some work. Sometimes I want this thread to die after the work is finished, other times I want it to wait for more work to do. To do this I pass in an Option<Receiver<T>>. If Option<Receiver<T>> is None the thread should die, else it should wait to receive more work.

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
            }
        }
    });
}

(link to playground)

The compiler says:

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

However if the Receiver is not enclosed in an Option everything is fine.

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

回答1:


When you write if let Some(r) = rx, you consume rx, making it unavailable for later.

You can use as_ref() to get a reference to the inner object instead, leaving rx usable:

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
            }
        }
    });
}

(link to playground)



来源:https://stackoverflow.com/questions/54993331/optionreceiver-moved-in-previous-loop-iteration

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!