Consider the following function (using ZlibDecoder
). It reads some data (just a random f64
in this case) from a reader that may or not be compressed. I use &mut dyn Read
to erase the fact that compression is used (or not).
fn read_data(reader: &mut (impl Read + Seek), is_compressed: bool) -> Result<f64> {
let start_pos = reader.stream_position()?;
let mut zlib_decoder;
let mut compressed_reader: &mut dyn Read = if !is_compressed {
reader
} else {
zlib_decoder = ZlibDecoder::new(reader);
&mut zlib_decoder
};
let data = compressed_reader.read_f64()?;
// Skip to next bit of data.
reader.seek(SeekFrom::Start(start_pos + 100))?;
Ok(data)
}
It almost works but it gives an error like this:
error[E0382]: borrow of moved value: `reader`
|
604 | fn read_data(reader: &mut (impl Read + Seek), is_compressed: bool) -> Result<f64> {
| ------ move occurs because `reader` has type `&mut impl Read + Seek`, which does not implement the `Copy` trait
...
621 | zlib_decoder = ZlibDecoder::new(reader);
| ------ value moved here
...
653 | reader.seek(SeekFrom::Start(start_pos + 100))?;
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ value borrowed here after move
Ok fair enough you can't just copy a &mut impl Read
- I guess that would give you two &mut
s to the same data which isn't allowed. But if I change the ZlibDecoder::new(reader)
line to this:
zlib_decoder = ZlibDecoder::new(&mut *reader);
Then it works! Can anyone tell me what is going on here? I kind of just guessed the solution and got lucky. I vaguely recall reading something about reborrowing and maybe it's something to do with that?