I am trying to implement the Iterator
trait for a struct which acts as a borrower of an array of i32
values, but I keep running into the compiler complaining about not being able to infer a lifetime inside the next method.
I am aware of Need help understanding Iterator lifetimes, but since my struct just borrows a slice of the array anyway, I keep the memory of the actual elements separate from my IntegerArrayBag
.
#[derive(Debug)]
struct IntegerArrayBag<'a> {
arr: &'a [i32],
idx: usize,
}
impl<'a> IntegerArrayBag<'a> {
fn len(&self) -> usize {
self.arr.len()
}
fn get(&self, idx: usize) -> Option<&i32> {
if self.arr.len() > idx {
Some(&self.arr[idx])
} else {
None
}
}
}
impl<'a> Iterator for IntegerArrayBag<'a> {
type Item = &'a i32;
fn next(&mut self) -> Option<&'a i32> {
let idx = self.idx;
self.idx += 1;
self.get(idx)
}
}
If I try to compile this code, the compiler complains with:
error[E0495]: cannot infer an appropriate lifetime for autoref due to conflicting requirements
--> src/main.rs:27:14
|
27 | self.get(idx)
| ^^^
|
note: first, the lifetime cannot outlive the anonymous lifetime #1 defined on the method body at 24:5...
--> src/main.rs:24:5
|
24 | / fn next(&mut self) -> Option<&'a i32> {
25 | | let idx = self.idx;
26 | | self.idx += 1;
27 | | self.get(idx)
28 | | }
| |_____^
note: ...so that reference does not outlive borrowed content
--> src/main.rs:27:9
|
27 | self.get(idx)
| ^^^^
note: but, the lifetime must be valid for the lifetime 'a as defined on the impl at 21:1...
--> src/main.rs:21:1
|
21 | / impl<'a> Iterator for IntegerArrayBag<'a> {
22 | | type Item = &'a i32;
23 | |
24 | | fn next(&mut self) -> Option<&'a i32> {
... |
28 | | }
29 | | }
| |_^
note: ...so that expression is assignable (expected std::option::Option<&'a i32>, found std::option::Option<&i32>)
--> src/main.rs:27:9
|
27 | self.get(idx)
| ^^^^^^^^^^^^^
You need to update your get
method to return a reference with longer life:
// Use 'a from impl<'a> IntegerArrayBag<'a>
fn get(&self, idx: usize) -> Option<&'a i32> {
and then it will compile.
Changing get(…)
to return Option<&'a i32>
makes it compile.
Playground URL: https://play.rust-lang.org/?gist=10783e90287b7111c126&version=stable
Gist URL: https://gist.github.com/10783e90287b7111c126
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With