什么时候应该使用`drain`和`into_iter`? [英] When should I use `drain` vs `into_iter`?

查看:142
本文介绍了什么时候应该使用`drain`和`into_iter`?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

从表面上看,它们两者都是 into_iter 提供类似的迭代器,即遍历集合的值.但是,它们是不同的:

On the surface, it looks like both drain and into_iter provide similar iterators, namely over the values of the collection. However, they are different:

fn main() {
    let mut items1 = vec![0u8, 1, 2, 3, 4, 5, 6, 7, 8, 9];
    let items2 = items1.clone();

    println!("{:?}", items1.drain().count());
    println!("{:?}", items2.into_iter().count());

    println!("{:?}", items1);
    // println!("{:?}", items2); Moved
}

drain&mut带到集合中,此集合随后可用. into_iter使用该集合.每个迭代器有什么适当的用途?

drain takes a &mut to the collection and the collection is available afterwards. into_iter consumes the collection. What are the appropriate uses for each iterator?

推荐答案

它们彼此之间有些多余.但是,正如您所说,Drain只是借用了向量,特别是它的寿命与向量有关.如果希望以最灵活的方式返回迭代器,或者使用其他方式迭代迭代器,则使用into_iter更好,因为它没有链接到原始Vec的所有者.如果希望重用数据结构(例如重用分配),则drain是最直接的方法.

They are somewhat redundant with each other. However, as you say, Drain just borrows the vector, in particular, it has a lifetime connected with the vector. If one is wishing to return an iterator, or otherwise munge iterators in the most flexible way possible, using into_iter is better, since it's not chained to the owner of the originating Vec. If one is wishing to reuse the data structure (e.g. reuse the allocation) then drain is the most direct way of doing this.

此外,(某种程度上)理论上的担忧是Drain 需要导致原始结构成为任何类型的有效实例,即保留不变式或修复不变式最后,IntoIter可以随意控制结构,因为它可以完全控制该值.

Also, a (somewhat) theoretical concern is that Drain needs to result in the originating structure being a valid instance of whatever type it is, that is, either preserve invariants, or fix them up at the end, while IntoIter can mangle the structure as much as it likes, since it has complete control of the value.

我只说有点"理论,因为在std中已经有一个很小的真实示例:HashMap通过其内部RawTable类型公开了.drain.into_iter,该类型也具有方法. into_iter可以阅读就是直接移动值的哈希值,仅此而已,但是drain必须小心

I say only "somewhat" theoretical because there is a small, real world example of this in std already: HashMap exposes .drain and .into_iter via its internal RawTable type, which also has those methods. into_iter can just read the hash of the value being moved directly and that's that, but drain has to be careful to update the hash to indicate that the cell is then empty, not just read it. Obviously this is absolutely tiny in this instance (probably only one or two additional instructions) but for more complicated data structures like trees there may be some non-trivial gains to be had from breaking the invariants of the data structure.

这篇关于什么时候应该使用`drain`和`into_iter`?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆