Stream: t-compiler/help

Topic: how to implement iterator with lifetime constrain


Derek (May 17 2020 at 22:08, on Zulip):

Hi I'm trying to implement a iterator return an item which contain a slice reference, I'm struggling to make my code pass compiling. Hope I can get some help here. Thanks for you time! here is simplified version:

use std::fmt;
struct Msg<'a> {
    id: u8,
    len: u8,
    data: &'a [u8],
}
impl<'a> fmt::Debug for Msg<'a> {
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
       write!(
           f,
           "msgid: {:?}, len: {:?} data: {:?}",
           self.id, self.len, self.data,
       )
   }
}
struct MsgParser<'a> {
    raw: &'a [u8],
    idx: u8,
}
impl<'a> MsgParser<'a> {
    fn from_slice(raw: &'a [u8]) -> MsgParser {
        MsgParser {
            raw,
            idx: 0
        }
    }
}
impl<'a> Iterator for Msg<'a> {
    type Item = Msg<'a>;
    fn next(&mut self) -> Option<Self::Item> {
        None
    }
}
fn main() {
    let buf = [1,4, 0,0,0,4,  2, 3, 0,0,6];
    let parser = MsgParser::from_slice(&buf);
    for v in parser {
        println!("{:?}", v);
    }
}

I expect output in each iteration like this:
msgid: 1, len: 4, data: [0,0,0,4]
msgid: 2, len: 3, data: [0,0,6]

But I got error:

for v in parser {
   |              ^^^^^^ `MsgParser<'_>` is not an iterator
   |
   = help: the trait `std::iter::Iterator` is not implemented for `MsgParser<'_>`
   = note: required by `std::iter::IntoIterator::into_iter`
Amanieu (May 18 2020 at 13:45, on Zulip):

Your code in the playground has a typo: it has impl<'a> Iterator for Msg<'a> instead of impl<'a> Iterator for MsgParser<'a>.

Last update: Sep 28 2020 at 16:45UTC