我在想如果你这样做会发生什么:
struct MyStruct
{
my_int: i32,
my_vec: Vec<i32>,
}
fn main() {
let my_box = std::boxed::Box::new(MyStruct::default());
let my_ref = *my_box;
}
当 my_box 超出范围时,将在 Box 上调用 drop 函数,这将对其成员调用 drop 函数。我假设 drop 函数就像 C++ 中的析构函数。
在 C++ 中,等价物是指向对象的 unique_ptr。当 unique_ptr 超出范围时,将调用其析构函数,这将调用 T 上的析构函数。假设 T 的移动赋值运算符编写正确,则不会发生任何情况。
在 Rust 中,动作具有破坏性。从编译器的角度来看,对象 (T) 已经不存在了,那么它仍然会在 Box 上调用 drop 吗?盒子仍然存在。
编辑:我在 MyStruct 上实现了 Drop 以打印到控制台,看起来 MyStruct 对象在移动后被 Box 丢弃。这是禁忌吗?未定义的行为?
当 my_box 超出范围时,会在 Box 上调用 drop 函数,同时也会对其内容调用 drop 函数。
即使您使用 let my_ref = *my_box; 将 MyStruct 从 Box 中移出,Box 仍然存在。 Box 负责释放它管理的内存,因此它会调用 MyStruct 的析构函数作为其自身销毁的一部分。
这不是未定义的行为。这是 Rust 中的预期行为,因为 Box 确保内容被正确释放,无论它们是否已被移动。只需确保在移动值后不要访问 my_box,因为它将不再保存有效数据。
struct MyStruct {
value: i32,
}
impl Drop for MyStruct {
fn drop(&mut self) {
println!("MyStruct with value {} is being dropped.", self.value);
}
}
fn main() {
let my_box = std::boxed::Box::new(MyStruct { value: 42 });
let my_ref = *my_box;
println!("my_ref has the value: {}", my_ref.value);
}