为什么将变量移动到生成的线程中即使没有复制也会通过借用检查器?这不是意味着它使用指向原始的指针吗?

问题描述 投票:0回答:1

我有这段代码,但我不明白为什么它可以编译:

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()
返回时,堆栈帧将被销毁,但线程仍将访问该位置的内存,并会破坏任何新调用函数的堆栈帧。

事实真的如此吗?如果不是,我做错了什么?

rust move-semantics borrow-checker
1个回答
5
投票

然后它被移动到闭包中,并且由于它没有在底层实现复制特征,因此将仅传递一个指针。

这是不正确的。当移动值时,实际数据(结构体或其他数据)也会被移动。在构造闭包之前,

State
位于堆栈变量中;之后,就处于关闭状态。没有指针,所以闭包不会借用任何东西。

如果您删除了行

let mut state = state;
then,则闭包不需要移动,而是借用
state
(或者更准确地说,它将借用
state.value
),即包含一个指针。

© www.soinside.com 2019 - 2024. All rights reserved.