0

I'm currently studying Rust Language by practice. My new challenge is to use store implement Iterator Trait to my data structure which role is to use an internal iterator over a Vec<String>:

impl<'a> CSVReader<'a> {

    pub fn new(lines: Vec<String>, nb_labels: u32, labels: Vec<String>, delim: char) -> Self {
        CSVReader {
            lines,
            iter: None,
            delim,
            nb_labels,
            labels
        }
    }
    
    fn update_iter(&'a mut self) {
        match &self.iter {
            Some(_) => (),
            None => { self.iter = Some(self.lines.iter()) }
        };
    }

    // ...
}

impl<'a> Iterator for CSVReader<'a> {
    type Item = Vec<String>;

    fn next(&mut self) -> Option<Self::Item> {
        self.update_iter();       // ------- line 66
        
        let line: String;
        if let Some(iter) = &mut self.iter {
            line = iter.next()?.clone();
            let cols: Vec<String> = line
            .split(self.delim)
            .map(|x| x.to_string())
            .collect();
            Some(cols)
        } else {
            None
        }    
    }

}

This code does not compile due to this error:

error[E0495]: cannot infer an appropriate lifetime for autoref due to conflicting requirements
  --> src/csv_parser/reader.rs:66:14
   |
66 |         self.update_iter();

I tried to add lifetime precision on the implementation of Iterator Trait but I get another error asking me to work with the right prototype of next() function.

I wish you could help me to understand why it doesn't work and provide some solutions to solve it :)

Shadow956
  • 9
  • 5
  • Can you provide an example that contains the definition of the `CSVReader` with all required imports? That way you could provide a [Minimal Reproducible Example](https://stackoverflow.com/help/minimal-reproducible-example) that will make it easier for others to help you solve your issue and for people with similar problems to get a complete solution to tinker with. – sebpuetz May 06 '21 at 10:51
  • Does this answer your question? [Why can't I store a value and a reference to that value in the same struct?](https://stackoverflow.com/questions/32300132/why-cant-i-store-a-value-and-a-reference-to-that-value-in-the-same-struct) – Maya May 06 '21 at 16:48

1 Answers1

0

You're trying to create a self-referential struct – where one of the fields references another. Doing this is hard, but not impossible. It is best to avoid self-referential struct when starting out, and you should use them sparingly either way.

I can see the following solutions:

  • Use an Iterator that owns the underlying vector, by vec.into_iter()
  • Store an index instead of a pointer
    • Note that this has just about no performance impact when the code is memory-bound.
  • Create a self-referential struct with the rental crate.
Maya
  • 1,490
  • 12
  • 24
  • Please don't recommend the rental crate, as it's (sadly) [no longer maintained or supported](https://github.com/jpernst/rental). – user4815162342 May 06 '21 at 15:20
  • @user4815162342 Could you recommend a maintained and supported alternative, then? – Maya May 06 '21 at 15:31
  • A list appears to be maintained [here](https://stackoverflow.com/a/32300133/1600898), although I can't personally recommend any of the alternatives as I haven't used them. Rental seemed the most advanced one, but I have a hunch that the plug wasn't pulled on it without good reason. – user4815162342 May 06 '21 at 15:58