Background: I'm creating an iterator that returns a reference to a slice &[T]
, but the data vector needs to remain immutable. The iterator cannot modify the original data, but must return the same slice pointer repeatedly after it has modified it. I've considered having my iterator own a Vec<T>
, but I would like to avoid that (and it didn't seem to work). I avoid allocations since I plan to use it mostly in realtime audio and allocations could potentially block. Code:
pub struct Windower<'a, 'b, T: 'a + 'b> {
window_type: WindowType,
hop_size: usize,
bin_size: usize,
current_index: usize,
data: &'a [T],
out_data: &'b mut [T]
}
impl<'a, 'b, T: Float + FromPrimitive> Iterator for Windower<'a, 'b, T> {
type Item = &'b [T];
fn next(&mut self) -> Option<Self::Item> {
if self.current_index < (self.len() - 1) {
let start = self.current_index * self.hop_size;
let end = start + self.bin_size;
self.current_index += 1;
let window = self.window();
let data_iter = self.data[start..end].iter();
for &mut v in self.out_data {
let val: T = window.next().unwrap() *
*data_iter.next().unwrap();
v = val;
}
Some(self.out_data)
} else {
None
}
}
}
Returns the error:
src/waves.rs:160:18: 160:31 error: cannot infer an appropriate lifetime for automatic coercion due to conflicting requirements [E0495]
src/waves.rs:160 Some(self.out_data)
^~~~~~~~~~~~~
src/waves.rs:146:5: 164:6 help: consider using an explicit lifetime parameter as shown: fn next(&'b mut self) -> Option<Self::Item>
I cannot figure out how to fix this. I can't make the change suggested, because the trait implementation for Iterator does not have an explicit lifetime parameter.
Rust prevents you from having more than one alias to an object if one of them is a mutable alias.
Here,
Windower::out_data
is a mutable alias to some slice, and you're trying to return an immutable alias to the same data from yournext
method. In order for this to be safe, Rust must prevent you from being able to useWindower::out_data
for as long as the slice returned bynext
is in scope. This means that the signaturefn next(&'b mut self) -> Option<Self::Item>
is indeed required, which means you simply cannot implementIterator
with your current implementation.