Option<Receiver> 在上一个循环迭代中移动

HiD*_*der 2 spawn receiver rust borrow-checker

我正在生成一个线程来做一些工作。有时我希望这个线程在工作完成后死亡,其他时候我希望它等待更多的工作去做。为此,我传入了一个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
            }
        }
    });
}
Run Code Online (Sandbox Code Playgroud)

链接到操场

编译器说:

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
            }
        }
    });
}
Run Code Online (Sandbox Code Playgroud)

但是,如果Receiver没有包含在一个中,Option一切都很好。

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

mca*_*ton 5

当您编写 时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
            }
        }
    });
}
Run Code Online (Sandbox Code Playgroud)

链接到操场