I'm trying to build an iterator that yields a reference to a Vec
. I'll try to explain my rationale to understand where my flaw is.
My first attempt was to have the iterator own the object:
pub struct VecIter<T> {
x: Vec<T>,
}
However, according to Iterator returning items by reference, lifetime issue, this would not work. There were two suggestions in the above answer: don't return a reference, or have a reference to the object.
Quoting from the answer:
For your specific, presumably simple example, you should either stop yielding references, or alter it so that your iterator object does not contain the data that you are iterating over—let it merely contain a reference to it, e.g. &'a [T] or even something like Items<'a, T>.
I want to implement the second option: i.e, return a reference by having the iterator contain a reference.
I've reduced the code to the simplest version that I cannot make it compile:
pub struct VecIter<'a, T> where T: 'a {
x: &'a mut Vec<T>,
}
impl<'a, T> VecIter<'a, T> {
fn next_(&'a mut self) -> Option<&'a Vec<T>> {
// do something to modify self.x
Some(self.x)
}
}
pub fn main() {
let mut vec_i = VecIter{x: &mut vec![100,200,300]};
while let Some(x) = vec_i.next_() {
// ...
}
}
I would expect the above code to work because each mutable borrow only lives inside the loop body. So the idea is to borrow the reference for the body of the loop, use it inside the loop, and end the borrow at the end of the loop.
Is it possible to build such an iterator? i.e., build an iterator that yields a reference to an object that it modifies in next()
?
EDIT:
In a comment by Matthieu M, it was suggested that for this to work I should:
remove the
'a
sonext_(&'a mut self)
becomesnext_(&mut self)
Maybe I'm understanding something wrong, but I tried this and I got the following compile error. To avoid any confusion here's the code that I tried (playground):
<anon>:8:14: 8:20 error: cannot infer an appropriate lifetime for automatic coercion due to conflicting requirements [E0495]
<anon>:8 Some(self.x)
^~~~~~
<anon>:6:5: 9:6 help: consider using an explicit lifetime parameter as shown: fn next_(&'a mut self) -> Option<&'a Vec<T>>
<anon>:6 fn next_(&mut self) -> Option<&'a Vec<T>> {
<anon>:7 // do something to modify self.x
<anon>:8 Some(self.x)
<anon>:9 }
error: aborting due to previous error
playpen: application terminated with error code 101