hi everybody,
I'm learning rust recently and writing some code to make sure I have a proper understanding of the concepts in Rust, I encountered something that puzzled me about lifetime, here is the code:
#[derive(Debug)]
struct C(Vec<u32>);
impl C {
fn iter<'a>(&'a self) -> CIter<'a> {
CIter {
c: self,
index: 0,
}
}
}
struct CIter <'a> {
c: &'a C,
index: usize,
}
impl <'a> Iterator for CIter<'a> {
type Item = &'a u32;
fn next(self:&mut CIter<'a>) -> Option<&'a u32> {
if self.index >= self.c.0.len() {
return None;
}
let next = &self.c.0[self.index];
self.index += 1;
return Some(next);
}
}
fn test_iter() {
let c = C(vec!(1,2,3));
for x in c.iter() {
println!("{:?}", *x);
}
let mut iter = c.iter();
let _ = iter.next();
println!("second element of c:{:?}", *iter.next().unwrap());
}
fn main() {
test_iter();
}
all above works fine, and then I'm trying to write a mutable Iterator and i got some compile error.
#[derive(Debug)]
struct C(Vec<u32>);
impl C {
fn iter<'a>(&'a self) -> CIter<'a> {
CIter {
c: self,
index: 0,
}
}
fn iter_mut<'a>(&'a mut self) -> CIterMut<'a> {
CIterMut {
c: self,
index: 0,
}
}
}
struct CIter <'a> {
c: &'a C,
index: usize,
}
impl <'a> Iterator for CIter<'a> {
type Item = &'a u32;
fn next(self:&mut CIter<'a>) -> Option<&'a u32> {
if self.index >= self.c.0.len() {
return None;
}
let next = &self.c.0[self.index];
self.index += 1;
return Some(next);
}
}
struct CIterMut <'a> {
c: &'a mut C,
index: usize,
}
impl <'a> Iterator for CIterMut<'a> {
type Item = &'a mut u32;
fn next(self:&mut CIterMut<'a>) -> Option<&'a mut u32> {
if self.index >= self.c.0.len() {
return None;
}
let next = &mut self.c.0[self.index];
self.index += 1;
return Some(next);
}
}
fn test_iter() {
let c = C(vec!(1,2,3));
for x in c.iter() {
println!("{:?}", *x);
}
let mut iter = c.iter();
let _ = iter.next();
println!("second element of c:{:?}", *iter.next().unwrap());
}
fn test_iter_mut() {
let c = C(vec!(1,2,3));
for x in c.iter_mut() {
println!("{:?}", *x);
}
let mut iter = c.iter_mut();
let _ = iter.next();
let r = iter.next().unwrap();
*r = 5;
println!("c: {:?}", c);
}
fn main() {
test_iter();
test_iter_mut();
}
finaly i got a compile error :
error[E0495]: cannot infer an appropriate lifetime for lifetime parameter in function call due to conflicting requirements
--> src/main.rs:47:25
|
47 | let next = &mut self.c.0[self.index];
| ^^^^^^^^^^^^^^^^^^^^
|
note: first, the lifetime cannot outlive the anonymous lifetime #1 defined on the method body at 43:5...
--> src/main.rs:43:5
|
43 | / fn next(self:&mut CIterMut<'a>) -> Option<&'a mut u32> {
44 | | if self.index >= self.c.0.len() {
45 | | return None;
46 | | }
... |
49 | | return Some(next);
50 | | }
| |_____^
note: ...so that reference does not outlive borrowed content
--> src/main.rs:47:25
|
47 | let next = &mut self.c.0[self.index];
| ^^^^^^^^
note: but, the lifetime must be valid for the lifetime `'a` as defined on the impl at 41:7...
--> src/main.rs:41:7
|
41 | impl <'a> Iterator for CIterMut<'a> {
| ^^
note: ...so that the types are compatible
--> src/main.rs:43:60
|
43 | fn next(self:&mut CIterMut<'a>) -> Option<&'a mut u32> {
| ____________________________________________________________^
44 | | if self.index >= self.c.0.len() {
45 | | return None;
46 | | }
... |
49 | | return Some(next);
50 | | }
| |_____^
= note: expected `std::option::Option<&'a mut u32>`
found `std::option::Option<&mut u32>`
It confuses me. All difference between CIter and CIterMut is the reference is mutalbe or immutable, the lifetime relation are all the same, but the compile error message told me the lifetime is wrong, why? Is there something I missed?
Thank you.