In a bid to understand lifetimes better I tried implementing a immutable and mutable iterator around a collection. Of course, the code is only for understanding purposes. But the mutable iterator implementation doesn't compile while the similar immutable version does. I know how to fix it, in the sense that I serendipitously arrived at the solution. But I don't understand how that works. I am pasting that too so someone could explain to me (a) why the first one does not and (b) why the second one does.
struct MyIterator<'a, T>
{
slice : &'a [T]
}
impl<'a, T> Iterator for MyIterator<'a, T>
{
type Item = &'a T;
fn next(&mut self) -> Option<Self::Item>
{
let (element, rest) = self.slice.split_first()?;
self.slice = rest;
Some(element)
}
}
struct MyMutableIterator<'a, T>
{
slice : &'a mut [T]
}
impl<'a, T> Iterator for MyMutableIterator<'a, T>
{
type Item = &'a mut T;
fn next(&mut self) -> Option<Self::Item>
{
let (element, rest) = self.slice.split_first_mut()?;
self.slice = rest;
Some(element)
}
}
I get the following the compilation error:
error: lifetime may not live long enough
--> src/main.rs:31:9
|
23 | impl<'a, T> Iterator for MyMutableIterator<'a, T>
| -- lifetime `'a` defined here
...
27 | fn next(&mut self) -> Option<Self::Item>
| - let's call the lifetime of this reference `'1`
...
31 | Some(element)
| ^^^^^^^^^^^^^ associated function was supposed to return data with lifetime `'a` but it is returning data with lifetime `'1`
Here is the version of the mutable iterator that works:
impl<'a, T> Iterator for MyMutableIterator<'a, T>
{
type Item = &'a mut T;
fn next(&mut self) -> Option<Self::Item>
{
let slice = &mut self.slice;
let slice = std::mem::replace(slice, &mut []);
let (element, rest) = slice.split_first_mut()?;
self.slice = rest;
Some(element)
}
}
The above version compiles. But I can't explain why?
Thanks in advance and Merry Xmas