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

Chr*_*ith 1 rust

这段代码不能编译...

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

...因为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
Run Code Online (Sandbox Code Playgroud)

为什么 Rustdata不像它那样移动wrap?有什么办法可以强制data一起移动wrap吗?

我的真实代码看起来更像这样。我接受一条消息,解析它,然后将它发送到一个线程进行处理。

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

我知道我可以修改我的Parsed结构以使用Strings 而不是&'a str,但是当编译器应该能够正常移动时这会降低效率data

use*_*342 7

为什么 Rustdata不像它那样移动wrap

几个原因 - 随你选择:

  1. 因为wrap被捕获,而不是data,闭包移动了被捕获的东西。

  2. 因为移动data将立即使wrap自身和其他引用无效(data如果它们存在)。此外,封闭范围本身可能需要data进一步访问。

  3. 因为这样就没有办法让闭包通过移动捕获一些值,而通过引用捕获一些值。目前,您可以创建一个闭包,move但仍然选择通过创建一个显式引用并捕获它来通过引用捕获某些值。您提出的功能将使这成为不可能。