Iterator returning slice: how?


#1

How do I rerturn slice frim iterator?

struct PageDecompressor {
    buff: Vec<u8>,
}

impl<'a> Iterator for PageDecompressor {
    type Item = &'a[u8];

    fn next(&mut self) -> Option<<Self as Iterator>::Item> {
        Some(&self.buff[..10])
    }
}

fn main() {}

gives me

error[E0207]: the lifetime parameter `'a` is not constrained by the impl trait, self type, or predicates
 --> src/main.rs:5:6
  |
5 | impl<'a> Iterator for PageDecompressor {
  |      ^^ unconstrained lifetime parameter

I want slice lifetime to be constrained to buffer time. Buffer is owned by PageDecompressor, but if I introduce lifetime in PageDecompressor, then compailr fails with “unused lifetime”. How do I communicate that returned item lifetime is constrained by iterator’s lifetime time?


#2

Items can’t be tied to an Iterator's own lifetime at all, sorry.

There would have to be lifetime like next(&'a mut self) to let the compiler understand users are only borrowing values, and since it’s mutable, this borrow would have to be released before you could call next() again. The current design of Iterator is such that you can call next() as many times as you like independently, and do things like collect() into another container.

You could instead have PageDecompressor implement IntoIterator, where there’s a separate Iterator type that references back to the PageDecompressor owned values.

You could also try implementing a different API, like StreamingIterator.


#3

@cuviper

his borrow would have to be released before you could call next()

Hmm, I think this is what I did not realize. As I modify buffer in next() call, lifetime of slice should be related to the call itself, othervise 2 calls to next() can override previous slice. I’ll try to follow examples you gave.