Влияет ли установка экземпляра Option с Some на None сбрасывание внутреннего значения? - PullRequest
1 голос
/ 10 июня 2019

У меня есть код:

struct Foo {}

impl Default for Foo {
    fn default() -> Self {
        Self {}
    }
}

impl Drop for Foo {
    fn drop(&mut self) {
        // Do something
    }
}

fn main() {
    {
        let foo = Some(Foo::default());
        let foo = None; // Would this line trigger `Foo::drop`?
    };
    {
        let mut foo = Some(Foo::default());
        foo = None; // Would this line trigger `Foo::drop`?
    };
}

Правильно ли высвобождены ресурсы, занятые foo?

Первая ситуация (переменная перезаписана) не сработает drop, поэтому я добавил вторую ситуацию, в которой я тоже запутался.

Ответы [ 2 ]

2 голосов
/ 10 июня 2019
let foo = Some(Foo::default());
let foo = None; // Would this line trigger `Foo::drop`?

Нет, конец блока будет.

Помните, что let является переменной объявлением , поэтому вторая строка не изменяетсяпервый foo, он создает новый foo, который скрывает первый.Но он все еще существует (и к нему можно получить доступ, если вы создали ссылку на него до второго let) до конца блока, поэтому он будет отброшен в конце блока.

Если вы хотитечтобы на самом деле изменить переменную, вы должны сделать

let mut foo = Some(Foo::default());
foo = None;

Теперь она немедленно вызовет удаление, потому что старое значение перезаписывается, поэтому оно должно удалить его.

2 голосов
/ 10 июня 2019

Если вы явно не указали имя переменной как _, оно будет удалено после завершения области действия.

В вашем случае переменные будут освобождены, когда соответствующая область действия закончится.

Поскольку вы реализуете черту Drop для Fooв явном виде.Он переопределит поведение drop и вызовет вашу функцию drop:

fn main() {
    let _: Option<Foo> = Some(Foo::default()); // Since variable name is '_' it will be dropped automatically.

    {
        let foo: Option<Foo> = Some(Foo::default());
        let foo: Option<Foo> = None;
        println!("Inner Scope Finishing. Going to drop inner scope variables.");
    } // Inner scope is finished dropping the inner scope variables.

    let main_foo: Option<Foo> = Some(Foo::default());
    let main_foo: Option<Foo> = None;
    println!("Main Scope Finishing. Going to drop main scope variables.");
} // Main is finished dropping the main scope variables

Детская площадка , чтобы показать поведение.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...