实现读取特征:特征绑定的`std :: error :: Error +'static:std :: marker :: Sized`不满意

时间:2018-07-21 09:12:23

标签: rust

我想为结构实现Read特性,以便在BufReader中使用它传递给库。该库使用BufReader作为输入,因为它应该与Stdin和实现Read的内存对象一起使用。

use std::error::Error;
use std::io::Read;

pub struct Test {
    counter: u8,
}

impl Test {
    pub fn new() -> Test {
        Test { counter: 0 }
    }
}

impl Iterator for Test {
    type Item = String;

    fn next(&mut self) -> Option<Self::Item> {
        if self.counter < 2 {
            self.counter += 1;
            return Some("String".to_string());
        }

        None
    }
}

impl Read for Test {
    fn read(&mut self, buf: &mut [u8]) -> Result<usize, Error> {
        let content = self.next();
        match content {
            None => Err(std::io::Error::new(
                std::io::ErrorKind::Other,
                "End of Iterator",
            )),
            Some(string) => {
                let mut i = 0;
                loop {
                    if i >= buf.len() || i >= string.len() {
                        break;
                    }

                    buf[i] = string[i];
                    i += 1;
                }

                Ok(i)
            }
        }
    }
}

fn main() {
    let test = Test::new();
    let reader = std::io::BufReader::new(test);
    // let filter = lib_that_uses_bufreader::useful_function(reader);
}

playground

尝试为该结构实现Read时,出现错误:

error[E0277]: the trait bound `std::error::Error + 'static: std::marker::Sized` is not satisfied
  --> src/main.rs:28:5
   |
28 | /     fn read(&mut self, buf: &mut [u8]) -> Result<usize, Error> {
29 | |         let content = self.next();
30 | |         match content {
31 | |             None => Err(std::io::Error::new(
...  |
48 | |         }
49 | |     }
   | |_____^ `std::error::Error + 'static` does not have a constant size known at compile-time
   |
   = help: the trait `std::marker::Sized` is not implemented for `std::error::Error + 'static`
   = note: required by `std::result::Result`

我自己构建了库,因此可以对其进行更改,但它与Stdin一起使用时效果很好,现在我想将其与结构一起使用。该库使用BufReader::lines,因此可以与迭代器进行交换,但是据我所知,这将破坏与Stdin的兼容性,因为我只能围绕{{ 1}},而不是迭代器。

如何解决此错误?哪个错误对象在编译时已知大小恒定?

1 个答案:

答案 0 :(得分:4)

返回

Result<usize, std::io::Error>

代替

Result<usize, Error>
您在签名中使用的

std::error::Error是一个特征。您不能直接返回特征。

您也可以这样做

Result<usize, Box<dyn Error>>

一个“特质对象”,但是我不明白为什么在这种情况下会这么做。