在Rust中克隆源自into_iter()的迭代器的成本?

iqih9akk  于 2023-11-19  发布在  其他
关注(0)|答案(2)|浏览(108)

我试图弄清楚在Rust中克隆源自into_iter()的迭代器的成本是多少,但找不到任何有意义的东西。
代码如下:

let v = vec![1,2,3,4,...]; // Some large vector
let iter = v.into_iter().map(...some closure...);
let another_iter = iter.clone(); // What is copied here??

字符串
由于我已经将向量移到迭代器中,iter现在拥有包含向量值的内部缓冲区,这正是我想要实现的抽象容器类型。
然而,当我调用iter.clone()时会发生什么呢?它是复制整个内部缓冲区的数据(可能非常昂贵)还是在引用同一个缓冲区时复制迭代器状态(便宜)?
有没有一种惯用的方法来存储和廉价地克隆这种源自into_iter()的迭代器?

eivgtgni

eivgtgni1#

由于每个IntoIterator实现都可以定义自己的type IntoIter: Iterator<Item = Self::Item>;,所以答案是它完全依赖于into_iter生成的迭代器。
对于std::vec::IntoIter,它正在克隆内部缓冲区,如Clone实现所示:

impl<T: Clone, A: Allocator + Clone> Clone for IntoIter<T, A> {
    #[cfg(not(test))]
    fn clone(&self) -> Self {
        self.as_slice().to_vec_in(self.alloc.deref().clone()).into_iter()
    }
    #[cfg(test)]
    fn clone(&self) -> Self {
        crate::slice::to_vec(self.as_slice(), self.alloc.deref().clone()).into_iter()
    }
}

字符串

disho6za

disho6za2#

它克隆整个缓冲区。本质上等于vec.clone(),除了它丢弃已经迭代的项目。你可以看到代码。
你也可以使用Itertools::tee(),但只有当Vec非常大并且你保持两个迭代器都围绕同一个项时,它才会更有效,所以不会有很大的滞后。甚至它的文档也警告说:

**注意:**如果迭代器是可克隆的,建议使用可克隆的迭代器,而不是使用这种方法。克隆可能会更有效。

相关问题