从表面上看,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使用集合。每个迭代器的适当用途是什么?
发布于 2015-01-11 01:01:32
他们彼此有点多余。但是,正如您所说的,Drain只是借用向量,特别是它与向量有一个生命周期。如果希望以最灵活的方式返回迭代器,或者以其他尽可能灵活的方式传递迭代器,则使用into_iter更好,因为它没有链接到原始Vec的所有者。如果希望重用数据结构(例如重用分配),那么drain是最直接的方法。
另外,(在某种程度上)理论上的关注是,Drain需要使原始结构成为任何类型的有效实例,也就是说,要么保留不变量,要么在末尾修正它们,而IntoIter可以随意破坏结构,因为它对值有完全的控制。
我说的只是“某种程度”的理论,因为在std中已经有这样的一个小的现实世界的例子:HashMap通过它的内部RawTable类型公开.drain和.into_iter,后者也有这些方法。into_iter可以只是读取要直接移动的值的散列。,这就是,但是drain必须小心更新散列以指示单元格随后为空。,而不仅仅是阅读它。显然,在这种情况下,这是绝对微小的(可能只有一两条额外的指令),但是对于更复杂的数据结构(如树),打破数据结构的不变量可能会带来一些非平凡的好处。
发布于 2015-01-11 01:02:02
使用drain后,Vec是空的,但是以前为其元素分配的存储仍然是分配的。这意味着您可以在Vec中插入新元素,而不必为它们分配存储,直到到达Vec的容量为止。
注意,在再次使用Vec之前,必须删除对Drain迭代器的所有引用。Drain的Drop实现将删除尚未从Vec中删除的所有元素,因此即使没有完成迭代,Vec也将是空的。
发布于 2021-04-11 22:01:32
2018年版“锈病”:
into_iter使用集合本身,drain只使用集合中的值。
因此,drain只允许耗尽集合的一部分,现在实际上需要指定一个范围。(问题提出后,这种情况似乎发生了变化。)
因此,如果要使用整个集合,则使用into_iter,如果只想使用集合的一部分或希望稍后重用空集合,则使用drain。
https://stackoverflow.com/questions/27882800
复制相似问题