I'm trying to iterate over a slice broken into chunks, and return a tuple with the nth element of each chunk.
Example:
&[1,2,3,4,5,6,7,8,9]
I'd like to break this into chunks of size 3, and then iterate over the results, returning these tuples, one on each next() call:
&[1,4,7], &[2,5,8], &[3,6,9]
So I made something like this:
use std::slice::Chunks;
pub struct MyIter<'a, T> {
chunks: Vec<Chunks<'a, T>>,
//This is so I have where to store the element that I want to return
current_tuple: Vec<T>
}
impl<'a, T> MyIter<'a, T> {
pub fn new(chunk_size: usize, slice: &'a[T]) -> MyIter<'a, T> {
let mut chunks = Vec::new();
let chunk_count = slice.len()/chunk_size;
for i in 0..chunk_count {
chunks.push(slice.chunks(chunk_size));
}
MyIter {
chunks,
current_tuple: Vec::new()
}
}
}
impl<'a, T: Copy> Iterator for MyIter<'a, T> {
type Item = &'a [T];
#[inline(always)]
fn next(&mut self) -> Option<Self::Item> {
for i in 0..self.chunks.len() {
self.current_tuple[i] = self.chunks[i].next().unwrap()[0];
}
Some(self.current_tuple.as_slice())
}
}
I quickly realized that returning a Vec<>
every time is going to allocate and deallocate lots of stuff, so I made one that sits in the struct, so I always return a reference to its internal slice. I think this is the problem though. I don't want to return vector copies though. I also cannot return an array or tuple because I only know the chunk amount in runtime
I get:
error[E0495]: cannot infer an appropriate lifetime for autoref due to conflicting requirements
--> src/lib.rs:32:33
|
32 | Some(self.current_tuple.as_slice())
| ^^^^^^^^
|
note: first, the lifetime cannot outlive the anonymous lifetime defined on the method body at 28:13...
--> src/lib.rs:28:13
|
28 | fn next(&mut self) -> Option<Self::Item> {
| ^^^^^^^^^
note: ...so that reference does not outlive borrowed content
--> src/lib.rs:32:14
|
32 | Some(self.current_tuple.as_slice())
| ^^^^^^^^^^^^^^^^^^
note: but, the lifetime must be valid for the lifetime `'a` as defined on the impl at 24:6...
--> src/lib.rs:24:6
|
24 | impl<'a, T: Copy> Iterator for MyIter<'a, T> {
| ^^
note: ...so that the types are compatible
--> src/lib.rs:28:46
|
28 | fn next(&mut self) -> Option<Self::Item> {
| ______________________________________________^
29 | | for i in 0..self.chunks.len() {
30 | | self.current_tuple[i] = self.chunks[i].next().unwrap()[0];
31 | | }
32 | | Some(self.current_tuple.as_slice())
33 | | }
| |_____^
= note: expected `Iterator`
found `Iterator`