当所有权开箱即用时,内存中会发生什么?

all*_*y87 5 heap-memory ownership rust

变量sinprint_struct是指堆上还是堆栈上的数据?

struct Structure {
    x: f64,
    y: u32,
    /* Use a box, so that Structure isn't copy */
    z: Box<char>,
}

fn main() {
    let my_struct_boxed = Box::new(Structure {
        x: 2.0,
        y: 325,
        z: Box::new('b'),
    });
    let my_struct_unboxed = *my_struct_boxed;
    print_struct(my_struct_unboxed);
}

fn print_struct(s: Structure) {
    println!("{} {} {}", s.x, s.y, s.z);
}
Run Code Online (Sandbox Code Playgroud)

据我了解,let my_struct_unboxed = *my_struct_boxed;将所有权从 box 转移到my_struct_unboxed,然后转移s到函数中print_struct

实际数据会发生什么?最初它是通过调用从堆栈复制到堆上的Box::new(...),但是数据是否在某些时候是如何移动或复制回堆栈的?如果是这样,如何?什么时候被drop调用?什么时候s超出范围?

ssh*_*124 4

Structure中的数据存在my_struct_boxed于堆上并且Structure中的数据my_struct_unboxed存在于堆栈中。

\n\n

因此,na\xc3\xafvely*来说(没有编译器优化),取消引用 ( )时的移动或复制操作Box将始终涉及数据复制。在借用检查器/静态分析方面,由于Copy未实现该特征Structure,因此这表示将数据所有权转移到my_struct_unboxed变量。

\n\n

当您调用 时print_struct,将进行另一个复制,将内存中代表您的位Structure从局部变量复制到函数的参数调用堆栈。从语义上讲,这再次代表了将所有权转移到该print_struct函数中。

\n\n

最后,当print_struct超出范围时,它会删除Structure它所拥有的。

\n\n
\n\n

参考:std::marker::Copy

\n\n

摘抄

\n\n
\n

需要注意的是,在这两个示例中,唯一的区别是赋值后是否允许您访问[您的变量]。在底层,复制和移动都可能导致位被复制到内存中,尽管有时会对此进行优化。

\n
\n\n

请注意最后一部分“这有时会被优化掉”。这就是为什么之前的描述被简化为假设没有编译器优化,即 na\xc3\xafve。在很多情况下,编译器会积极优化和内联代码,尤其是在标志值较高的情况下opt-level

\n