Где задокументировано, что Опция <T>является Drop? - PullRequest
0 голосов
/ 18 февраля 2019

Я надеялся, что если я оберну Box<T> в Option, падение просто сделает свое дело.И эта программа действительно выводит «отброшено»:

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);
}

Детская площадка

Я проверил документацию как Option и Drop и я не смог найти описание этого поведения.Я пропустил какое-то волшебство компилятора, или я прав, что он не может быть реализован в другом месте, только в объявлении черты или в определении разработчика?

Как Option реализует Drop и почему он отсутствует в документации

1 Ответ

0 голосов
/ 18 февраля 2019

В документах не упоминается, что Option<T> реализует Drop, потому что он не реализует его.

Черта Drop необходима, только если вы хотите, чтобы ваша структура или перечисление имели некоторые особое поведение.Если вам нужно только освободить память и запустить деструкторы дочерних элементов, компилятор сделает это самостоятельно.С соответствующей страницы в Rustonomicon :

Если структура не имеет специальной логики для удаления, кроме удаления своих дочерних элементов, то это означает, что Drop не нужнобыть реализованным вообще!

Option не имеет реализации Drop, потому что в его уничтожении нет специальной логики, в отличие от Rc (который уменьшает счетчик ссылок) или с MutexGuard (который разблокирует родительский мьютекс).Вы можете наблюдать то же поведение с вашими собственными типами, Bar s в 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>() {}
  | ^^^^^^^^^^^^^^^^^^^^^^^^^^^
...