Reputation: 184
Having code like
#[derive(Debug)]
struct BinaryVec {
vec: Vec<u8>,
}
impl BinaryVec {
fn empty() -> BinaryVec {
BinaryVec { vec: Vec::new() }
}
fn push(&mut self, bit: u8) {
self.vec.push(bit);
}
}
I'd like to be able to iterate over the structure's vector without making it public. For example, to call it like:
let bin_vec = BinaryVec::empty();
bin_vec.push(1);
bin_vec.push(0);
bin_vec.push(1);
for el in bin_vec.iter() {
// do something with 1,0,1 elements
}
But I see that Iterator
trait requires only next
method which assumes the saved iter state in the structure.
Is there any way to directly pass vec iter through the higher level struct in Rust without adding new state related fields to the struct?
Upvotes: 12
Views: 4320
Reputation: 8224
Vec<T>
itself does not implement Iterator
either. However, it implements IntoIterator
in three ways:
impl<T> IntoIterator for Vec<T>
: you can write for item in vec
, and each item
will take a T
by value. This consumes the vector.impl<T> IntoIterator for &'_ [T]
(where &Vec<T>
derefs to &[T]
): you can write for item in &vec
, and each item
will take a &T
.impl<T> IntoIterator for &'_ mut [T]
(where &mut Vec<T>
derefs to &mut [T]
): you can write for item in &mut vec
, and each item
will take a &mut T
.You probably wanted to implement these for your wrapper as well:
impl IntoIterator for BinaryVec {
type Item = u8;
type IntoIter = <Vec<u8> as IntoIterator>::IntoIter; // so that you don't have to write std::vec::IntoIter, which nobody remembers anyway
fn into_iter(self) -> Self::IntoIter {
self.vec.into_iter()
}
}
// We deref to slice so that we can reuse the slice impls
impl Deref for BinaryVec {
type Output = [u8];
fn deref(&self) -> &[u8] {
&self.vec[..]
}
}
impl DerefMut for BinaryVec {
type Output = [u8];
fn deref_mut(&mut self) -> &mut [u8] {
&mut self.vec[..]
}
}
Note that implementing IntoIterator
for &mut [T]
is not trivial (you need to use stuff methods split_first_mut
if you don't want to write unsafe code), so better reuse the implementation from slices.
Upvotes: 9
Reputation: 133
Actually, to call it as you described, you don't need to implement Iterator
for it.
You just need to return the iterator of the inner vec:
impl BinaryVec {
...
fn iter(self: &Self) -> impl Iterator<Item=u8>{
self.vec.iter()
}
}
Note that even the standard Vec
doesn't implement Iterator
, It's the struct that iter
returns that implements it.
Upvotes: 10