1 year ago
#375268
SupaGu
How to resolve lifetime iterator impl error
I have a data structure called 'FluidSim' which is a bunch of cells. Think of a 2d grid (x,y) which then holds a vector of data for each cell (grid location).
I want to make an iterator which lets me iterator over this grid (and in future I want to be able to skip empty cells).
Additionally I want some additional functionality on the iterator to help get data out of the data structure (or put data into it).
get_cell_index is an example function where I am trying to do that.
I'm having trouble getting the Iterator impl working:
struct FluidSimIterator<'a> {
fluid_sim: &'a FluidSim,
ix: usize,
iy: usize,
skip_empty_buckets: bool
}
impl FluidSimIterator<'_> {
pub fn get_cell_index(&self) -> usize {
return self.ix + (self.fluid_sim.bucket_size * self.iy);
}
}
impl FluidSim {
pub fn iter(&self) -> FluidSimIterator {
FluidSimIterator{
fluid_sim: self,
ix: 0,
iy: 0,
skip_empty_buckets: true
}
}
}
impl<'a> Iterator for FluidSimIterator<'a> {
type Item = &'a mut FluidSimIterator<'a>;
fn next(&mut self) -> Option<Self::Item> {
self.ix += 1;
Some(self)
}
}
The errors I am seeing are:
error[E0495]: cannot infer an appropriate lifetime due to conflicting requirements
--> physics/src/fluid_sim.rs:666:9
|
666 | Some(self)
| ^^^^^^^^^^
|
note: first, the lifetime cannot outlive the anonymous lifetime defined here...
--> physics/src/fluid_sim.rs:664:13
|
664 | fn next(&mut self) -> Option<Self::Item> {
| ^^^^^^^^^
note: ...so that reference does not outlive borrowed content
--> physics/src/fluid_sim.rs:666:14
|
666 | Some(self)
| ^^^^
note: but, the lifetime must be valid for the lifetime `'a` as defined here...
--> physics/src/fluid_sim.rs:661:6
|
661 | impl<'a> Iterator for FluidSimIterator<'a> {
| ^^
note: ...so that the types are compatible
--> physics/src/fluid_sim.rs:664:46
|
664 | fn next(&mut self) -> Option<Self::Item> {
| ______________________________________________^
665 | | self.ix += 1;
666 | | Some(self)
667 | | }
| |_____^
= note: expected `<FluidSimIterator<'a> as Iterator>`
found `<FluidSimIterator<'_> as Iterator>`
error: aborting due to previous error
For more information about this error, try `rustc --explain E0495`.
full source code is here: https://github.com/bit-shift-io/fluidic-space/blob/main/crates/physics/src/fluid_sim.rs with this above snippet right at the bottom of the file.
Seems it is something to do with lifetimes which I am still wrapping my head around. SO not exactly sure what the error is saying or how to resolve it.
EDIT:
I managed to get working how I want it to, although I'm not sure how 'ideal' the solution is:
pub struct Iter<'a> {
pub fluid_sim: &'a FluidSim,
pub ix: isize,
pub iy: isize
}
impl<'a> Iterator for Iter<'a> {
type Item = Iter<'a>; //Cell<'a>; //&'a Cell;
fn next(&mut self) -> Option<Self::Item> {
self.ix += 1;
if self.ix >= self.fluid_sim.x_size as isize {
self.iy += 1;
if self.iy >= self.fluid_sim.y_size as isize {
return None
}
self.ix = 0;
}
let dup = Iter{
fluid_sim: self.fluid_sim,
ix: self.ix,
iy: self.iy
};
Some(dup)
}
}
impl FluidSim {
pub fn iter(&self) -> Iter {
Iter {
fluid_sim: &self,
ix: -1,
iy: 0
}
}
}
And a basic example of the usage looks like:
let mut h1 = FluidSim::new(3, 3);
for cell in h1.iter() {
println!("x: {:?}, y: {:?}", cell.ix, cell.iy)
}
gives me the following output:
x: 0, y: 0
x: 1, y: 0
x: 2, y: 0
x: 3, y: 0
x: 0, y: 1
x: 1, y: 1
x: 2, y: 1
x: 3, y: 1
x: 0, y: 2
x: 1, y: 2
x: 2, y: 2
x: 3, y: 2
x: 0, y: 3
x: 1, y: 3
x: 2, y: 3
x: 3, y: 3
So I can now add other functions on my Iter struct to read and write into the correct cell of my fluid_sim struct.
rust
iterator
0 Answers
Your Answer