print_struct
中的变量s
是指堆上的数据还是堆栈上的数据?
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
,然后在函数print_struct
中s
。
实际数据会发生什么情况?最初它是通过调用Box::new(...)
从堆栈复制到堆上的,但是数据是否在某个时候移动或复制回堆栈?如果是这样,如何?什么时候叫drop
?当s
超出范围时?
my_struct_boxed
中的Structure
数据存在于堆上,my_struct_unboxed
中的Structure
数据存在于堆栈中。
因此,天真地说(没有编译器优化(,取消引用(*
(Box
时的移动或复制操作将始终涉及复制数据。在借用检查器/静态分析方面,由于Copy
特征没有实现Structure
,这表示数据的所有权转移到my_struct_unboxed
变量。
当你调用print_struct
时,将发生另一个副本,它将内存中代表你的Structure
的位从局部变量复制到函数的参数调用堆栈。从语义上讲,这再次表示所有权转移到print_struct
函数中。
最后,当print_struct
超出范围时,它会丢弃它拥有的Structure
。
参考资料:std::marker::Copy
摘录
需要注意的是,在这两个示例中,唯一的区别 是赋值后是否允许您访问 [您的变量]。在 Hood,复制和移动都可能导致位被复制到 内存,尽管有时会将其优化掉。
请注意最后一部分"这有时会被优化掉"。这就是为什么早期的描述被简化为假设没有编译器优化,即幼稚。在很多情况下,编译器会积极优化和内联代码,尤其是opt-level
标志的值较高时。
">如果是这样,如何?
复制"和"移动"在语义上都是memcpy
的(尽管这可以优化为其他内容,甚至什么都没有(。
什么时候叫
drop
?当s
超出范围时?
是的。当print_struct
结束时,它会清理其本地范围,并删除s
。