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/