在哪里记录Option <t>为Drop?

时间:2019-02-18 20:00:32

标签: rust destructor traits

我希望,如果我将Box<T>包装到Option中,则放下就可以了。并且该程序确实输出“ dropped”:

trait Foo {}

struct Bar {}

impl Foo for Bar {}

impl Drop for Bar {
    fn drop(&mut self) {
        println!("dropped")
    }
}

fn main() {
    let x = Box::new( Bar {} ) as Box<Foo>;
    let _y = Option::Some(x);
}

Playground

我检查了OptionDrop的文档,但找不到此行为的描述。我是否错过了一些编译器魔术,还是对,就不能在特征声明或实现者定义中其他地方实现?

Option如何实现Drop?为什么文档中没有它?

1 个答案:

答案 0 :(得分:4)

文档没有提到Option<T>实现Drop的原因,因为它没有实现。

仅当您希望结构或枚举具有某些特殊行为时才需要Drop特性。如果您唯一需要的是释放内存并运行子元素的析构函数,则编译器将自行执行此操作。在Rustonomicon的相关页面中:

  

如果一个结构除了删除其子级外没有其他特殊的逻辑,则意味着Drop根本不需要实现!

Option没有Drop的实现,因为它的销毁没有涉及特殊的逻辑,与Rc(使引用计数器递减)或MutexGuard(解锁父互斥体)。您可以使用自己的类型观察到相同的行为,Bar中的struct Thingie(Bar, Bar)将被丢弃,就像包裹在Some中一样。

请注意,“ X上方没有Drop实现”的所有地方实际上意味着没有实现-编译器不会隐式地实现。

您还可以直接测试类型是否实现Drop

fn test_for_drop<T: Drop>() { }

fn main() {
    test_for_drop::<Option<i32>();
}

Playground

这会产生错误:

  
error[E0277]: the trait bound `std::option::Option<i32>: std::ops::Drop` > is not satisfied
 --> src/main.rs:4:5
  |
4 |     test_for_drop::<Option<i32>>();
  |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `std::ops::Drop` is not implemented for `std::option::Option<i32>`
  |
note: required by `test_for_drop`
 --> src/main.rs:1:1
  |
1 | fn test_for_drop<T: Drop>() {}
  | ^^^^^^^^^^^^^^^^^^^^^^^^^^^