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

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只是借用了向量,特别是,它的生命周期与向量有关。如果希望返回迭代器,或者希望以最灵活的方式返回迭代器,则使用into_iter更好,因为它没有链接到原始Vec的所有者。如果希望重用数据结构(例如重用分配),那么drain是最直接的方法。

同样,(某种程度上)理论上的担心是Drain需要导致原始结构成为其有效类型的有效实例,也就是说,保留不变式或将其固定在末尾,而IntoIter可以将结构修改为就像它喜欢的那样,因为它可以完全控制值。

我说的只是理论上的“有点”,因为std中已经有一个小而真实的示例:HashMap通过其内部.drain类型公开了.into_iterRawTable,该类型也具有这些方法。 into_iter可以只是read the hash of the value being moved directly,仅此而已,但是drain必须小心to update the hash to indicate that the cell is then empty,而不仅仅是阅读它。显然,在这种情况下,这绝对是很小的(可能只有一条或两条额外的指令),但是对于像树这样的更复杂的数据结构,打破数据结构的不变性可能会带来一些不小的收获。

关于iterator - 我什么时候应该使用 `drain`和 `into_iter`?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/27882800/

10-09 02:43