【问题标题】:Option<Receiver> Moved in Previous Loop IterationOption<Receiver> 在上一个循环迭代中移动
【发布时间】:2019-07-26 08:39:56
【问题描述】:

我正在生成一个可以做一些工作的线程。有时我希望这个线程在工作完成后死掉,有时我希望它等待更多的工作去做。为此,我传递了Option&lt;Receiver&lt;T&gt;&gt;。如果Option&lt;Receiver&lt;T&gt;&gt;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
            }
        }
    });
}

(link to playground)

编译器说:

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!"),
            }
        }
    });
}

【问题讨论】:

  • 第一种情况,如果你调用foo(None),它会启动一个线程,进入循环,测试失败,中断循环,停止线程。那为什么还要启动一个线程呢?你确定不想要Receiver&lt;Option&lt;usize&gt;&gt; 吗?这似乎更有意义。
  • @mcarton 我发布了一个修剪过的线程。 //Does work 评论代表了大量未显示的工作。如果在线程中传入一个新的usize,会调整一些参数并重做工作。

标签: rust spawn borrow-checker receiver


【解决方案1】:

当您写入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
            }
        }
    });
}

(link to playground)

【讨论】:

  • 或者只是&amp;rx,我们没有这个副本吗?
猜你喜欢
  • 2015-08-27
  • 2023-03-13
  • 1970-01-01
  • 1970-01-01
  • 2023-04-10
  • 1970-01-01
  • 2015-07-09
  • 1970-01-01
  • 2016-02-25
相关资源
最近更新 更多