Object objects and read n bytes into a vector

Let's say I have the following:

use std::io;
use std::io::Read;

#[derive(Debug)]
enum FooReadError {
    UnexpectedEof,
    IoError(io::Error),
}

impl From<io::Error> for FooReadError {
    fn from(err: io::Error) -> FooReadError {
        FooReadError::IoError(err)
    }
}

fn read_n_bytes_to_vector<R: Read>(reader: &mut R, length: usize)
        -> Result<Vec<u8>, FooReadError> {
    let mut bytes = Vec::<u8>::with_capacity(length);
    unsafe { bytes.set_len(length); }
    let bytes_read = try!(reader.read(&mut bytes[..]));
    if bytes_read != length {
        Err(FooReadError::UnexpectedEof)
    } else {
        Ok(bytes)
    }
}

fn do_some_read(reader: &mut Read) -> Vec<u8> {
    read_n_bytes_to_vector(reader, 16).unwrap()
}

fn main() {
    let v = vec![0, 1, 2, 3, 4, 5];
    let mut cur = io::Cursor::<Vec<u8>>::new(v);
    do_some_read(&mut cur);
}

      

It is supposed to read_n_bytes_to_vector

take something that implements the trait io::Read

, reads length

bytes from it and puts them into a vector and returns a vector.

A function do_some_read

has an object object io::Read

. So why then:

% rustc ./vec_read.rs
./vec_read.rs:29:5: 29:27 error: the trait `core::marker::Sized` is not implemented for the type `std::io::Read` [E0277]
./vec_read.rs:29     read_n_bytes_to_vector(reader, 16).unwrap()
                     ^~~~~~~~~~~~~~~~~~~~~~
./vec_read.rs:29:5: 29:27 note: `std::io::Read` does not have a constant size known at compile-time
./vec_read.rs:29     read_n_bytes_to_vector(reader, 16).unwrap()
                     ^~~~~~~~~~~~~~~~~~~~~~

      

I agree with the compiler that io::Read

I cannot implement Sized

; but I'm passing the feature object - they are persistent, so it should be fine here; ** so why the error? * But wait, why does it even matter? The function does not accept io::Read

arg (right?) For an argument, it also accepts a trait object, because arg is generic and must take the full type passed.

+3


source to share


1 answer


General options include Sized

default snapping ; if you don't want this to be necessary you must add the binding ?Sized

.

The object object is not constant in size; u16 as Trait

- two bytes, u32 as Trait

- four bytes, and; only objects such as objects with a box stroke ( Box<Trait>

) and object references ( &Trait

, &mut Trait

) have a constant size known at compile time (two words for the examples given).



Since you are only R

using the mutable link link, you can successfully add the anchor ?Sized

:

fn read_n_bytes_to_vector<R: ?Sized + Read>(reader: &mut R, length: usize)
        -> Result<Vec<u8>, FooReadError> {

      

+4


source







All Articles