Файлы немного особенные.Обычные методы read()
и seek()
и write()
(определенные для черт Read
, Seek
и Write
) принимают self
по изменяемой ссылке:
fn read(&mut self, buf: &mut [u8]) -> Result<usize>
fn seek(&mut self, pos: SeekFrom) -> Result<u64>
fn write(&mut self, buf: &[u8]) -> Result<usize>
Однако,все упомянутые черты также реализованы для &File
, то есть для неизменных ссылок на файл:
Таким образом, вы можете изменить файл, даже если у вас есть только ссылка только для чтения нафайл.Для этих реализаций тип Self
равен &File
, поэтому принятие self
с помощью изменяемой ссылки фактически означает принятие &mut &File
, изменяемой ссылки на ссылку на файл.
Ваш код проходит&f
до BzDecoder::new()
, создавая неизменный заем.Позже вы звоните f.seek(SeekFrom::Current(0))
, который передает f
в seek
по изменяемой ссылке.Однако это не разрешено, поскольку у вас уже есть неизменный заем файла.Решение состоит в том, чтобы использовать Seek
реализацию вместо &File
:
(&mut &f).seek(SeekFrom::Current(0))
или немного проще
(&f).seek(SeekFrom::Current(0))
Это только создает второй неизменный заем, который разрешен Rust'sправила для ссылок.
Я создал пример игровой площадки, демонстрирующий, что это работает .Если вы замените (&f)
на f
, вы получите ошибку, которую вы изначально получили.