В стандартной библиотеке BufWriter объявлен следующим образом:

pub struct BufWriter<W: Write> {
    inner: Option<W>,
    buf: Vec<u8>,
    // #30888: If the inner writer panics in a call to write, we don't want to
    // write the buffered data a second time in BufWriter's destructor. This
    // flag tells the Drop impl if it should skip the flush.
    panicked: bool,
}

Как говорится в документации, panicked существует как защита от двойной записи при размотке, и я понимаю причины этого. Есть ли аналогичная причина для того, чтобы внутренний писатель был заключен в Option? Единственная часть, которую я нахожу в коде, где фактически очищается Option, находится в into_inner, но я не вижу причин, по которым это не должно быть возможным и с голым значением, как self, как принято значение.

3
HeroicKatora 26 Фев 2018 в 04:15

1 ответ

Лучший ответ

Причина проста: BufWriter реализует Drop, и вы не можете выйти из поля из типа, который реализует Drop. Непосредственно перед возвратом BufWriter::into_inner вызывается BufWriter::drop, потому что BufWriter перемещается в параметр функции self, а затем выпадает из области видимости - это стандартный RAII.

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

4
Francis Gagné 26 Фев 2018 в 04:35