mem::ManuallyDrop 类与 mem::forget() 函数
ManuallyDropT
的析构函数 (基于 Drop
trait 实现的).
可以用它来调整结构体中成员的 drop 顺序.
看下面一个例子:
use std::mem::ManuallyDrop; pub struct Sheep { name: String, } pub struct Cow { name: String, } pub struct Horse { name: String, } impl Drop for Sheep { fn drop(&mut self) { println!("Dropping sheep {}", self.name); } } impl Drop for Cow { fn drop(&mut self) { println!("Dropping cow {}", self.name); } } impl Drop for Horse { fn drop(&mut self) { println!("Dropping horse {}", self.name); } } pub struct Animals { sheep: ManuallyDrop<Sheep>, #[allow(dead_code)] horse: Horse, cow: ManuallyDrop<Cow>, } impl Drop for Animals { fn drop(&mut self) { println!("Dropping animals"); unsafe { // 手动调用 `drop()` 释放这两个对象. ManuallyDrop::drop(&mut self.sheep); ManuallyDrop::drop(&mut self.cow); // 而 horse 对象会被自动释放. } } } #[allow(unused_variables)] fn main() { let animals = Animals { sheep: ManuallyDrop::new(Sheep { name: "Doly".to_owned(), }), horse: Horse { name: "Tom".to_owned(), }, cow: ManuallyDrop::new(Cow { name: "Jery".to_owned(), }), }; // 使用 mem::forget() 会导致内存泄露 //mem::forget(animals); }
查看上面例子的打印日志, 可以发现结构体 Animals
的析构顺序是:
- Animals
- Sheep
- Cow
- Horse
而下面的代码是结构体的一般写法, 其析构顺序是:
- Animals
- Sheep
- Horse
- Cow
struct Animals {
sheep: Sheep,
horse: Horse,
cow: Cow,
}
mem::forget()
函数
forget()
函数就是利用了 ManuallyDrop
类, 看看该函数的实现:
pub const fn forget<T>(t: T) {
let _ = ManuallyDrop::new(t);
}
不正确的使用 forget()
函数会产生内存泄露, 看一个例子:
use std::mem; fn main() { let msg = String::from("Hello, Rust"); mem::forget(msg); // msg 的堆内存没有被释放, 产生了内存泄露 }