我一直在读Rust的书,在第15.3章中介绍了Drop特性。它说trait对于实现智能指针很重要(第二个对智能指针模式很重要的trait是Drop",但是从提供的示例中我看不出为什么:
struct CustomSmartPointer {
data: String,
}
impl Drop for CustomSmartPointer {
fn drop(&mut self) {
println!("Dropping CustomSmartPointer with data `{}`!", self.data);
}
}
fn main() {
let c = CustomSmartPointer {
data: String::from("my stuff"),
};
let d = CustomSmartPointer {
data: String::from("other stuff"),
};
println!("CustomSmartPointers created.");
}
它们只是在超出作用域之前打印容器所拥有的值(据我所知,无论如何它都会被丢弃)。
关于这个,他们说:"我们在这里打印一些文本来直观地演示Rust何时调用drop ">
对,但是没有提供任何例子来说明这个特性实际上是如何有用的(除了可能释放的日志资源,我猜)。
所以我的问题是:Drop实现在这种情况下有多重要?提交它是否会导致内存泄漏或其他问题?我觉得我完全没抓住重点。有人能提供一个用例,除了在超出范围之前打印值之外,还能做其他事情吗?
我试图删除drop实现,但这并没有改变任何东西,除了当CustomSmartPointer超出范围时没有打印任何东西的事实。没有编译错误。
在很多情况下,当一个值被删除时,您可能想要执行一些操作。
- 您正在手动管理内存。这甚至不需要使用本地api;可以使用
Box::into_raw
/Box::leak
和Box::from_raw
。 - 你正在本地操作系统资源(如文件句柄或网络套接字)上实现Rust接口。当rust端值被删除时,你需要告诉操作系统销毁资源。
- 你在一些第三方库上实现了一个Rust接口。考虑一下SQLite、libpcap等。当Rust句柄被删除时,你想要清理该库中的资源。
- 你正在实现一个警卫,像
RefCell
或Mutex
警卫。当保护被解除时,您需要调整引用计数或释放锁。 - 你正在实现一个连接池。当池连接被丢弃时,您希望将连接返回到池中,以便以后可以重用它。
在大多数应用程序中,可能很少需要手动实现Drop
。然而,它是RAII习惯用法的关键部分,因此您将在实现该习惯用法的地方看到它。