为了提高效率,所有迭代器适配器都按值获取原始迭代器。此外,获得原始迭代器的所有权可以避免在不需要时处理生存期。
如果希望保留对原始迭代器的访问,可以使用
by_ref
. 这引入了一个间接层次,但是程序员选择在需要特性时进行额外的工作:
fn main() {
let v = [1, 2, 3, 4, 5, 6, 7, 8];
let mut i1 = v.iter();
for z in i1.by_ref().take_while(|&&v| v < 4) {
// ^^^^^^^^^
println!("Take While: {}", z);
}
for z in i1 {
println!("Rest: {}", z);
}
}
有输出
Take While: 1
Take While: 2
Take While: 3
Rest: 5
Rest: 6
Rest: 7
Rest: 8
Iterator::by_ref
因为有一个
Iterator
对于迭代器的任何可变引用:
impl<'_, I> Iterator for &'_ mut I
where
I: Iterator + ?Sized,
这意味着您还可以采用可变引用。优先顺序需要括号:
for z in (&mut i1).take_while(|&&v| v < 4)
你注意到了吗
4
他失踪了?那是因为有一次
take_while
选择一个值并决定不使用它,它没有地方“放回去”。把它放回去需要选择
更多
存储和速度比通常需要的慢。
我用过
itertools crate
专门处理这样的案子
take_while_ref
:
use itertools::Itertools; // 0.9.0
fn main() {
let v = [1, 2, 3, 4, 5, 6, 7, 8];
let mut i1 = v.iter();
for z in i1.take_while_ref(|&&v| v < 4) {
// ^^^^^^^^^^^^^^^
println!("Take While: {}", z);
}
for z in i1 {
println!("Rest: {}", z);
}
}
Take While: 1
Take While: 2
Take While: 3
Rest: 4
Rest: 5
Rest: 6
Rest: 7
Rest: 8