首页 文章

特征对象,并将n个字节读入矢量

提问于
浏览
3

说我有以下,

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);
}

read_n_bytes_to_vector 应该采取任何实现特征 io::Read ,从中读取 length 字节,并将它们放入一个向量并返回向量 .

函数 do_some_read 有一个 io::Read 特征对象 . 那么,为什么呢:

% 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()
                     ^~~~~~~~~~~~~~~~~~~~~~

我同意编译器 io::Read 不可能实现 Sized ;但是我传递了一个特征对象 - 那些是恒定大小的,所以它应该没问题; **那么为什么会出错?*等等,为什么它甚至重要?该函数没有为arg取得 io::Read (对吗?),它传递了's taking a trait object too, because the arg is generic, and should take the full type of what' .

1 回答

  • 4

    泛型包含默认绑定的 Sized ;如果您不希望它是必需的,则必须添加 ?Sized 界限 .

    特质对象的大小不一定; u16 as Trait 是两个字节, u32 as Trait 是四个字节,&c . ;只有盒装特征对象( Box<Trait> )和特征对象引用( &Trait&mut Trait )之类的东西具有恒定的大小,在编译时已知(引用的例子中有两个字) .

    因为您只使用 R by mutable reference,所以可以成功添加 ?Sized 绑定:

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

相关问题