handle.join().unwrap(); println!("主线程不能再用 data 了"); }
输出:
拿到: [1, 2, 3] 主线程不能再用 data 了
如果去掉 move,编译会报错:
error[E0373]: closure may outlive the current function, but it borrows `data`, which is owned by the current function --> e5.rs:6:32 | 6 | let handle = thread::spawn(|| { | ^^ may outlive borrowed value `data` 7 | println!("拿到: {:?}", data); | ---- `data` is borrowed here | note: function requires argument type to outlive `'static` --> e5.rs:6:18 | 6 | let handle = thread::spawn(|| { | __________________^ 7 | | println!("拿到: {:?}", data); 8 | | }); | |______^ help: to force the closure to take ownership of `data` (and any other referenced variables), use the `move` keyword | 6 | let handle = thread::spawn(move || { | ++++
关键在 may outlive borrowed value:data 借给闭包,闭包可能被移到另一个线程上,而 data 属于主线程的栈帧,主线程可能先退出。编译器无法证明借用能活到闭包用完,所以直接拒绝。
error[E0277]: `Rc<i32>` cannot be sent between threads safely --> e2.rs:6:19 | 6 | thread::spawn(move || { | ------------- ^------ | | _____|_____________within this `{closure@e2.rs:6:19: 6:26}` | | | | | ____|_____required by a bound introduced by this call 7 | | println!("{}", data); 8 | | }); | |_____^ `Rc<i32>` cannot be sent between threads safely | = help: within `{closure@e2.rs:6:19: 6:26}`, the trait `Send` is not implemented for `Rc<i32>` note: required because it's used within this closure --> e2.rs:6:19 | 6 | thread::spawn(move || { | ^^^^^^^ note: required by a bound in `spawn` --> /rustc/31fca3adb283cc9dfd56b49cdee9a96eb9c96ffd/library/std/src/thread/functions.rs:125:0