从表面上看, 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_iter
和RawTable
,该类型也具有这些方法。 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/