[英]How do I implement a non-consuming IntoIterator for a struct with an underlying collection?
Let's say I have a struct
that has a collection, such as a Vec
as one of its data members:假设我有一个具有集合的
struct
,例如Vec
作为其数据成员之一:
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:我希望
MyCollection
的用户能够在不直接访问Vec
本身的情况下迭代其数据,如下所示:
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
.但是,我正在努力使用
&x
为非消费版本实现必要的 Trait IntoIterator
。 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
.消耗
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
:到目前为止,这是我基于
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 Copy
able, but this yields the following:我还尝试删除
type Item
的&'a
,因为在我的情况下, 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
I understand the function wants an IntoIter
of a vector to references, but I'm unsure how to give it one efficiently.我知道该函数需要一个向量的
IntoIter
来引用,但我不确定如何有效地给它一个。 I'm new to Rust, so I'd much appreciate some clarity on the concern.我是 Rust 的新手,所以我非常感谢您对这个问题的一些澄清。 Bonus points if you can also tell me how to create a mutable iterator for write access in the same fashion.
如果您还可以告诉我如何以相同的方式创建用于写访问的可变迭代器,则可以加分。
First, you should use slice type, your user shouldn't have to know that you inner type is vector.首先,您应该使用切片类型,您的用户不必知道您的内部类型是向量。 Then, your problem is that you must not use
IntoIter
type, but Iter
type directly.那么,你的问题是你不能使用
IntoIter
类型,而是直接使用Iter
类型。
Simple example:简单的例子:
struct MyCollection {
data: Vec<i32>,
}
impl<'a> std::iter::IntoIterator for &'a MyCollection {
type Item = <std::slice::Iter<'a, i32> as Iterator>::Item;
type IntoIter = std::slice::Iter<'a, i32>;
fn into_iter(self) -> Self::IntoIter {
self.data.as_slice().into_iter()
}
}
fn main() {
let x = MyCollection {
data: vec![1, 2, 3, 4, 5],
};
for i in &x {
println!("{}", i);
}
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.