Just a simple question, for which I don't seem to find an answer.
Is there any reason why an array (with a fixed size), doesn't implement the std::io::Read trait, while a slice does implement it?
The following code doesn't work:
fn sample<R: std::io::Read>(reader: R) {}
fn main() {
let x = [0x00] as [u8; 1];
sample(x);
}
While the following code does work:
fn sample<R: std::io::Read>(reader: R) {}
fn main() {
let x: &[u8] = &[0x00];
sample(x);
}
The Read trait has as a primary method
fn read(&mut self, buf: &mut [u8]) -> Result<usize>
that operates on a mutable object. The implementor of Read has to keep track of which bytes are and aren’t consumed yet. The implementation for &[u8] does this by an implementation for &[u8] references, not for [u8] directly:
fn read(self: &mut &[u8], buf: &mut [u8]) -> Result<usize>
resulting in a nested reference type. The implementation the operates by modifying the &[u8] behind the mutable reference, by trimming the slice to the remaining unconsumed part.
Here’s the implementation. Note the *self = b; line, where b comes from let (a, b) = self.split_at(amt);
You can use an array for io::Read if you augment it by some state tracking the position. This is exactly what Cursor can do. So just use Cursor<[u8; 1]> I guess?
Thanks for the clear explanation. It makes sense now.