Hi
I've been trying to make my implementation for Iterator
over mutable slice.
I know how to fix the code below, but I don't quite understand why the following code does not work (I've added explicit lifetimes for clarity here).
I will write how I understand it,and would be great if someone corrected me if I'm wrong
struct MyIterMut<'a> {
slice: &'a mut [u8],
}
impl<'a> Iterator for MyIterMut<'a> {
type Item = &'a u8;
fn next<'b>(&'b mut self) -> Option<Self::Item>{
if (self.slice.is_empty()) { return None;}
let (l, r) = self.slice.split_at_mut(1);
self.slice = r;
l.get_mut(0)
}
}
The compiler says
error: lifetime may not live long enough
--> src\main.rs:13:9
|
5 | impl<'a> Iterator for MyIterMut<'a> {
| -- lifetime `'a` defined here
...
8 | fn next<'b>(&'b mut self) -> Option<Self::Item>{
| -- lifetime `'b` defined here
...
13 | l.get_mut(0)
| ^^^^^^^^^^^^ method was supposed to return data with lifetime `'a` but it is returning data with lifetime `
|
= help: consider adding the following bound: `'b: 'a`
Since self
is only borrowed, I cannot move self.slice
with lifetime 'a
into a local variable and proceed with it. I can only reborrow it to call split_at_mut()
on slice
(this method borrows mutably).
So self.slice
gets lifetime 'b
(because self has lifetime 'b
). And its complete type is &'b mut &'a mut [u8]
And then comes the piece that I don't quite understand. The type &'b mut &'a mut [u8]
does not have method split_at_mut()
, but &mut [u8]
does have it.
So &'b mut &'a mut [u8]
should be derefenced via DerefMut
and it gets lifetime 'b
being derferenced to &'b mut [u8]
because lifetime elision happens in defef_mut()
, which signature is
fn deref(&self) -> &Self::Target {}
So split_at_mut()
gets called on a reference with lifetime 'b
, so l
and r
get lifetime 'b
as well through lifetime elision and all breaks because the function is supposed to return a reference with lifetime 'a
.
Is this understanding correct?