s中的变量print_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);
}

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

实际数据会怎样?最初,通过调用Box::new(...)将其从堆栈复制到堆上,但是数据在某个时候是如何移动或复制回堆栈的?如果是这样,怎么办?何时调用drop?当s超出范围时?

最佳答案

堆中存在Structure中的my_struct_boxed数据,而堆栈中存在Structure中的my_struct_unboxed数据。

因此,天真地讲(没有编译器优化),在取消引用(*)时,移动或复制操作Box将始终涉及数据的复制。在借位检查器/静态分析方面,由于没有为Copy实现Structure特性,所以这表示将数据所有权转移到my_struct_unboxed变量。

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

最后,当print_struct超出范围时,它将删除其拥有的Structure

Reference: std::marker::Copy

摘抄



请注意最后一部分“有时会对其进行优化”。这就是为什么将先前的描述简化为假设没有任何编译器优化的原因。在许多情况下,编译器会积极地优化和内联代码,尤其是对于opt-level标志使用更高的值时。

关于rust - 当所有权从盒子中转移出来时,内存中会发生什么?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/59628211/

10-10 18:33