如何为具有基础集合的结构实现非消耗性的IntoIterator?

时间:2020-01-17 01:45:06

标签: loops rust iterator iteration

假设我有一个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的新手,所以我非常感谢您对此问题的澄清。如果您还可以告诉我如何以相同的方式为写访问创建一个可变的迭代器,则可以得到加分。

0 个答案:

没有答案