简体   繁体   English

为什么`move` 不随引用一起移动引用数据?

[英]Why doesn't `move` move referenced data along with the reference?

This code does not compile...这段代码不能编译...

fn main() {
    let data = "hi".to_string();
    let wrap = &data;
    std::thread::spawn(move || println!("{}", wrap));
}

...because data doesn't live inside the spawned thread: ...因为data不存在于生成的线程中:

error[E0597]: `data` does not live long enough
 --> src/main.rs:3:16
  |
3 |     let wrap = &data;
  |                ^^^^^ borrowed value does not live long enough
4 |     std::thread::spawn(move || println!("{}", wrap));
  |     ------------------------------------------------ argument requires that `data` is borrowed for `'static`
5 | }
  | - `data` dropped here while still borrowed

Why doesn't Rust move data like it does wrap ?为什么 Rust 不像wrap那样移动data Is there any way to force data to be moved along with with wrap ?有没有办法强制datawrap一起移动?

My real code looks more like this.我的真实代码看起来更像这样。 I accept a message, parse it, and then send it to a thread for processing.我接受一条消息,解析它,然后将它发送到一个线程进行处理。

struct Message {
    data: Vec<u8>,
}
let message = Message {
    data: "{\"name\":\"Rust\"}".to_string(),
};

#[derive(Deserialize)]
struct Parsed<'a> {
    name: &'a str,
}
let parsed: Parsed = serde_json::from_slice(&message.data).unwrap();

std::thread::Builder::new()
    .name(parsed.name) // note: need some of the parsed data prior to moving into the thread...so cannot solve with JSON parsing inside thread
    .spawn(move || println("{}", parsed.name));

I know I could modify my Parsed struct to use String s instead of &'a str , but this reduces efficiency when the compiler should be able to move data just fine.我知道我可以修改我的Parsed结构以使用String s 而不是&'a str ,但是当编译器应该能够很好地移动data时,这会降低效率。

Why doesn't Rust move data like it does wrap为什么 Rust 不像wrap那样移动data

Several reasons - take your pick:几个原因 - 随你选择:

  1. Because wrap is captured, not data , and the closure moves what is captured.因为wrap被捕获,而不是data ,并且闭包会移动捕获的内容。

  2. Because the move of data would immediately invalidate both wrap itself and other references to data if they exist.因为data的移动会立即使wrap本身和其他data引用(如果存在)无效。 Also, the enclosing scope might itself need data for further access.此外,封闭范围本身可能需要data以供进一步访问。

  3. Because then there would be no way to have a closure that captures some values by move and some by reference.因为这样就没有办法让闭包通过移动捕获一些值,而通过引用捕获一些值。 Currently you can make a closure move but still elect to capture certain values by reference simply by creating an explicit reference and capturing that.目前,您可以进行闭包move但仍然选择通过创建一个显式引用并捕获它来通过引用捕获某些值。 The feature you propose would make that impossible.您提出的功能将使这成为不可能。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM