借用检查器“无法摆脱借来的内容”

时间:2018-06-19 03:14:05

标签: rust

为什么我不能这样做?

pub fn start_workers(&mut self) {
    // start all the worker threads
    self.dispatch_thread = Some(spawn(||{
        for _i in 1..10 {
            println!("Price = {}", 10);
            thread::sleep(time::Duration::from_secs(1));
        }
    }));
    self.dispatch_thread.unwrap().join();
}

我收到以下错误,

  
error[E0507]: cannot move out of borrowed content
   --> src/orderbook.rs:195:9
    |
195 |         self.dispatch_thread.unwrap().join();
    |         ^^^^ cannot move out of borrowed content

1 个答案:

答案 0 :(得分:3)

这确实是一个非显而易见的错误消息。看一下unwrap的方法签名:

pub fn unwrap(self) -> T

take

pub fn take(&mut self) -> Option<T>

unwrap使用Option(请注意接收方为self),这会使self.dispatch_thread处于未知状态。如果您使用take,则会按照您的意图返回None状态。

在这种情况下你可能想要take;如下所示:

use std::thread;
use std::time;

struct Foo {
    foo: Option<thread::JoinHandle<()>>,
}

impl Foo {
    fn nope(&mut self) {
        self.foo = Some(thread::spawn(|| {
            for _i in 1..10 {
                println!("Price = {}", 10);
                thread::sleep(time::Duration::from_millis(10));
            }
        }));
        self.foo.take().unwrap().join();
    }
}

fn main() {
    let foo = Some(thread::spawn(|| {
        for _i in 1..10 {
            println!("Price = {}", 10);
            thread::sleep(time::Duration::from_millis(10));
        }
    }));
    foo.unwrap().join();

    let mut foo = Foo { foo: None };
    foo.foo = Some(thread::spawn(|| {
        for _i in 1..10 {
            println!("Price = {}", 10);
            thread::sleep(time::Duration::from_millis(10));
        }
    }));
    foo.foo.unwrap().join();

    let mut foo = Foo { foo: None };
    foo.nope();
}

请注意,assert!(foo.foo.is_none());同样是非法的;但在这种情况下有效,因为我们没有违反该约束。在&self作为接收者的方法中,这不是真的,这就是为什么在这种情况下它是非法的。