I'm new to rust and I've been stuck with this problem for a while: Iter
iterators that do the same thing compile, but IterMut
does not.
I don't understand why the mutator interprets &mut self
's lifecycle as '1
instead of 'a
? The fact that the Iter iterator compiles means that the compiler interprets &mut self
s lifecycle as 'a
, so why doesn't it work for IterMut
I found two related threads, but neither mentioned this. Why it is wrong for IterMut
to use this pattern?
The mutable reference lifetime problem of iterators
How does Vec’s iterator return a mutable reference
pub struct IterMut<'a, T> {
inner: &'a mut Vec<T>,
index: usize,
}
impl<'a, T> Iterator for IterMut<'a, T> {
type Item = &'a mut T;
fn next(&mut self) -> Option<Self::Item> {
let item = self.inner.get_mut(self.index);
self.index += 1;
item
}
}
pub struct Iter<'a, T> {
inner: &'a Vec<T>,
index: usize,
}
impl<'a, T> Iterator for Iter<'a, T> {
type Item = &'a T;
fn next(&mut self) -> Option<Self::Item> {
let item = self.inner.get(self.index);
self.index += 1;
item
}
}
error: lifetime may not live long enough
--> src/main.rs:1984:9
|
1978 | impl<'a, T> Iterator for IterMut<'a, T> {
| -- lifetime `'a` defined here
...
1981 | fn next(&mut self) -> Option<Self::Item> {
| - let's call the lifetime of this reference `'1`
...
1984 | item
| ^^^^ method was supposed to return data with lifetime `'a` but it is returning data with lifetime `'1`
And the third omission rule for lifecycle doesn't seem to work here either. The first code compiles fine, but when I don't identify the lifecycle for the Item, the compiler won't allow it.
pub struct Iter<'a, T> {
inner: &'a Vec<T>,
index: usize,
}
impl<'a, T> Iterator for Iter<'a, T> {
type Item = &'a T;
fn next(&mut self) -> Option<Self::Item> {
let item = self.inner.get(self.index);
self.index += 1;
item
}
}
pub struct Iter<'a, T> {
inner: &'a Vec<T>,
index: usize,
}
impl<'a, T> Iterator for Iter<'a, T> {
type Item = &T;
fn next(&mut self) -> Option<Self::Item> {
let item = self.inner.get(self.index);
self.index += 1;
item
}
}
error[E0637]: `&` without an explicit lifetime name cannot be used here
--> src/main.rs:1994:17
|
1994 | type Item = &T;
| ^ explicit lifetime name needed here
error: lifetime may not live long enough
--> src/main.rs:1999:9
|
1993 | impl<'a, T> Iterator for Iter<'a, T> {
| -- lifetime `'a` defined here
...
1999 | item
| ^^^^ returning this value requires that `'a` must outlive `'static`