假设我有一个struct
,其中有一个集合,例如Vec
作为其数据成员之一:
struct MyCollection {
data: Vec<i32>
}
我希望MyCollection
的用户能够迭代其数据而无需直接访问Vec
本身,就像这样:
let x = MyCollection{data:vec![1, 2, 3, 4, 5]};
for i in &x {
//...
}
但是,我正在努力为使用IntoIterator
的非消费版本实现必要的特性&x
。我已经成功实现了消费版本:
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();
}
}
但是,这只能按以下方式使用:
for i in x {
println!("{:?}", i);
}
消耗x
。克隆数据是可能的,但是非常昂贵,所以我想避免这种情况。
到目前为止,这是我基于std::vec::Vec
的{{3}}创建的非消费版本的内容:
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();
}
}
会产生以下编译错误:
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
我还尝试删除了&'a
中的type Item
,因为在我的情况下,data
的元素是Copy
可用的,但这会产生以下结果:>
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
我知道该函数需要一个IntoIter
的矢量来引用,但是我不确定如何有效地给它一个。我是Rust的新手,所以我非常感谢您对此问题的澄清。如果您还可以告诉我如何以相同的方式为写访问创建一个可变的迭代器,则可以得到加分。