我有这段代码,但我不明白为什么它可以编译:
use std::thread;
use std::time::Duration;
struct State {
value: u32,
}
impl State{
pub fn new() -> State{
State{ value: 0 }
}
}
fn main() {
run_thread();
for i in 1..10 {
println!("hi number {i} from the main thread!");
thread::sleep(Duration::from_millis(300));
}
}
fn run_thread(){
let state = State::new();
thread::spawn(|| {
let mut state = state;
for i in 1..10 {
state.value = i;
println!("hi number {i} from the spawned thread!");
thread::sleep(Duration::from_millis(300));
}
});
}
据我了解,
run_thread()
中的变量状态是在堆栈上分配的。然后它被移动到闭包中,并且由于它没有在引擎盖下实现 Copy
特性,因此只会传递一个指针。但是,当 run_thread()
返回时,堆栈帧将被销毁,但线程仍将访问该位置的内存,并会破坏任何新调用函数的堆栈帧。
事实真的如此吗?如果不是,我做错了什么?
然后它被移动到闭包中,并且由于它没有在底层实现复制特征,因此将仅传递一个指针。
这是不正确的。当移动值时,实际数据(结构体或其他数据)也会被移动。在构造闭包之前,
State
位于堆栈变量中;之后,就处于关闭状态。没有指针,所以闭包不会借用任何东西。
如果您删除了行
let mut state = state;
then,则闭包不需要移动,而是借用 state
(或者更准确地说,它将借用 state.value
),即包含一个指针。