Drop 特征

用于实现 Drop 的值可以指定在超出范围时运行的代码:

  1. struct Droppable {
  2. name: &'static str,
  3. }
  4. impl Drop for Droppable {
  5. fn drop(&mut self) {
  6. println!("Dropping {}", self.name);
  7. }
  8. }
  9. fn main() {
  10. let a = Droppable { name: "a" };
  11. {
  12. let b = Droppable { name: "b" };
  13. {
  14. let c = Droppable { name: "c" };
  15. let d = Droppable { name: "d" };
  16. println!("Exiting block B");
  17. }
  18. println!("Exiting block A");
  19. }
  20. drop(a);
  21. println!("Exiting main");
  22. }

This slide should take about 8 minutes.

  • 请注意,std::mem::dropstd::ops::Drop::drop 不同。
  • 当值超出范围时,系统会自动将其删除。
  • 丢弃某个值时,如果该值实现了 std::ops::Drop,则会调用其 Drop::drop 实现。
  • 然后,该值所有字段也会被丢弃,无论其是否实现了 Drop
  • std::mem::drop 只是一个采用任何值的空函数。重要的是它获得了值的所有权,因此在其作用域结束时便会被丢弃。如此您可以轻松提前明确地丢弃值,而不必等到值超过范围的时候。
    • 这对于通过 drop 执行任务的对象来说非常有用,例如释放锁、关闭文件等。

讨论点:

  • 为什么 Drop::drop 不使用 self
    • 简答:如果这样的话,系统会在代码块结尾 调用 std::mem::drop,进而引发再一次调用 Drop::drop,并引发堆栈 溢出!
  • 尝试用 a.drop() 替换 drop(a)