I have a struct that has an iterator over a borrowed slice, and I want to create a method that returns an iterator that does some computation on the contained iterator
Basically this:
#[derive(Clone)] struct Foo<'a> { inner: ::std::iter::Cycle<::std::slice::Iter<'a, u8>>, } impl<'a> Foo<'a> { pub fn new<T: AsRef<[u8]> + ?Sized>(vals: &'a T) -> Foo<'a> { Self { inner: vals.as_ref().iter().cycle(), } } pub fn iter(&mut self) -> impl Iterator<Item = u8> + 'a { self.inner.by_ref().map(Clone::clone) // simple case but this could be any computation } } Which yields a cryptic error.
Here's my understanding: I need to bind the returned iterator's lifetime to the &mut self of iter() so that &mut self is only dropped when .collect() is called on the returned iterator.
BUT, changing to fn iter(&'a mut self) isn't good enough because &'a mut self now lives for the entire duration of the struct instance (meaning that calling collect() doesn't drop that reference). Which prevents something like this
#[test] fn test(){ let mut foo = Foo::new("hello, there"); foo.iter().zip(0..4).collect::<Vec<_>>(); // call once, ok foo.iter().zip(0..4).collect::<Vec<_>>(); // error because 2 &mut references exist at the same } rust playground link
innerin the struct definition such that the struct gets parameterised by'a, you could just make the type ofinnergeneric.