Let's say I have a struct that has a collection, such as a Vec as one of its data members:
struct MyCollection {
data: Vec<i32>
}
I want the user of MyCollection to be able to iterate over its data without direct access to the Vec itself, like so:
let x = MyCollection{data:vec![1, 2, 3, 4, 5]};
for i in &x {
//...
}
However, I'm struggling with implementing the necessary Trait IntoIterator for the non-consuming version with &x. I have successfully implemented the consuming version:
impl std::iter::IntoIterator for MyCollection {
type Item = i32;
type IntoIter = std::vec::IntoIter<Self::Item>;
fn into_iter(self) -> Self::IntoIter {
return self.data.into_iter();
}
}
However, this is only usable as follows:
for i in x {
println!("{:?}", i);
}
which consumes x. Cloning the data is possible, but quite expensive, so I'd like to avoid that.
Here is what I have so far for the non-consuming version, which I based on the source implementation of std::vec::Vec:
impl<'a> std::iter::IntoIterator for &'a MyCollection {
type Item = &'a i32;
type IntoIter = std::vec::IntoIter<Self::Item>;
fn into_iter(self) -> Self::IntoIter {
return self.data.into_iter();
}
}
which produces the following compile error:
error: mismatched types
error: expected &i32, found i32
note: expected type `std::vec::IntoIter<&i32>`
found type `std::vec::IntoIter<i32>`
error: expected `std::vec::IntoIter<&i32>` because of return type
I have also tried removing the &'a of the type Item since in my case, the elements of data are Copyable, but this yields the following:
error: cannot move out of `self.data` which is behind a shared reference
error: move occurs because `self.data` has type `std::vec::Vec<i32>`, which does not implement the `Copy` trait
I understand the function wants an IntoIter of a vector to references, but I'm unsure how to give it one efficiently. I'm new to Rust, so I'd much appreciate some clarity on the concern. Bonus points if you can also tell me how to create a mutable iterator for write access in the same fashion.