克隆一个迭代器是否会复制整个底层向量?

5

我想要多次迭代一个向量:

let my_vector = vec![1, 2, 3, 4, 5];
let mut out_vector = vec![];
for i in my_vector {
    for j in my_vector {
        out_vector.push(i * j + i + j);
    }
}

j循环存在“移动后使用值”错误。我知道我可以在两个 my_vector 之前放置&并借用向量,但拥有多种解决方法是很好的。我也想要一些见解。

或者,我可以编写以下内容:

let i_vec = vec![1, 2, 3, 4, 5, 6];
let iterator = i_vec.iter();
let mut out_vec = vec![];
for i in iterator.clone() {
    for j in iterator.clone() {
        out_vec.push(i * j + i + j);
    }
}

我看了一下关于如何在Rust中高效重用迭代器的问题:

What's the most efficient way to reuse an iterator in Rust?

:

通常情况下,如果所有“部分”都支持Clone,则迭代器是可克隆的。

实际堆分配的数据是迭代器的“部分”还是指向堆数据的内存地址是上述“部分”?
1个回答

7
克隆切片迭代器(当调用Vec或数组上的iter()时,会得到此类型的迭代器)不会复制底层数据。两个迭代器仍然指向存储在原始向量中的数据,因此克隆操作很便宜。
其他类型的可克隆迭代器可能也是如此。
在您的情况下,您可以多次调用i_vec.iter()而不是调用i_vec.iter()并对其进行克隆。
for i in i_vec.iter() {
    for j in i_vec.iter() {

这种方法得到的结果相同,但更易读。


我猜测使用 i_vec.iter() 两次不会受到借用检查器的惩罚,因为我们没有将 i_vec 绑定到任何东西。 - Dragon
1
@Dragon 它能正常工作是因为每次都采用只读引用,而且可以有多个引用。你原来的代码问题在于 for i in my_vector 消耗了向量(它用于将数据移出向量),所以在此之后你不能再使用该向量。 - interjay
1
更加惯用的写法(正如Clippy所告诉你的)是 for i in &i_vec { for j in &i_vec { ... }} - Shepmaster
@Shepmaster:这是真的,但问题已经提到了那个方法,所以我在我的答案中没有提到它。 - interjay

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接