从表面上看,它看起来像两者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
}
Run Code Online (Sandbox Code Playgroud)
drain
需要&mut
收集和收集可用之后.into_iter
消耗该集合.每个迭代器的适当用途是什么?
huo*_*uon 14
它们彼此有些多余.但是,如你所说,Drain
只是借用向量,特别是它有一个与向量连接的生命周期.如果一个人希望以最灵活的方式返回迭代器,或以其他方式使用迭代器,则使用into_iter
更好,因为它不会链接到原始的所有者Vec
.如果一个人希望重用数据结构(例如重用分配),那么这drain
是最直接的方式.
另外,(某种程度上)理论上的关注是Drain
需要导致原始结构是它的任何类型的有效实例,即,保留不变量,或者在最后修复它们,同时IntoIter
可以破坏结构.它喜欢,因为它完全控制了价值.
我只是说"有些"理论,因为现在有一个小的,现实世界的例子std
:HashMap
暴露.drain
和.into_iter
通过其内部RawTable
类型,也有这些方法.into_iter
可以只读取直接移动的值的哈希就是这样,但drain
必须小心更新哈希以指示该单元格是空的,而不仅仅是读取它.显然这在这种情况下是非常小的(可能只有一两个附加指令)但是对于像树一样的更复杂的数据结构,可能会有一些非平凡的收益来打破数据结构的不变量.
Jan*_*nis 11
对于 2018 版 Rust:
into_iter
消耗集合本身,drain
仅消耗集合中的值。
因此drain
只允许排出集合的一部分,现在实际上需要指定一个范围。(自从提出问题以来,这似乎已经发生了变化。)
因此,into_iter
如果您想使用整个集合,请使用它;drain
如果您只想使用集合的一部分,或者如果您想稍后重用清空的集合,则请使用。