I'm a Rust newbie and I'm trying to implement a custom struct
that has Vec
. I'd like this custom struct to be iterable and that iterates on the inner Vec
in reverse order.
So far what I understood is that I need to implement the IntoIterator
trait and eventually a custom Iterator
to which the IntoIterator
transforms the custom struct. Since I just want to reverse the iteration on the Vec
, I was thinking to re-use what the standard lib offers already.
This is my struct:
pub struct BitMap {
content: Vec<u64>,
}
and this is how I was trying to implement the IntoIterator
:
impl<'a> iter::IntoIterator for &'a BitMap {
type Item = u64;
type IntoIter = iter::Rev<slice::Iter<'a, Self::Item>>;
fn into_iter(self) -> Self::IntoIter {
(&(self.content)).iter().rev()
}
}
But the compiler complains about:
47 | type IntoIter = iter::Rev<slice::Iter<'a, Self::Item>>;
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected `u64`, found reference
I'm struggling to understand how I can achieve this simple thing.
UPDATE
Thanks E_net4 says don't copy that for your answer!
Considering that you mentioned that your solution would require copying the elements, I tried to implement a version that tries to avoid it and this is what I came up with:
impl<'a> iter::IntoIterator for &'a BitMap {
type Item = u64;
type IntoIter = BitMapIterator<'a>;
fn into_iter(self) -> Self::IntoIter {
BitMapIterator::new(&self.content)
}
}
pub struct BitMapIterator<'a> {
content: &'a Vec<u64>,
index: usize,
}
impl<'a> BitMapIterator<'a> {
fn new(content: &'a Vec<u64>) -> Self {
BitMapIterator {
content,
index: content.len(),
}
}
}
impl iter::Iterator for BitMapIterator<'_> {
type Item = u64;
fn next(&mut self) -> Option<Self::Item> {
if self.index == 0 {
None
} else {
self.index -= 1;
Some(self.content[self.index])
}
}
}
But as you can see, this required me to implement also a custom Iterator and make it public. This seems to do what I want and if I'm understanding correctly without copying the elements, but I don't know how idiomatic this solution is and it basically doesn't re-use anything provided by std lib.