我发现奇怪的是Iterator::take_while
取得了迭代器的所有权。它似乎是一个有用的功能,能够使第一个 x 元素满足某些功能,但仍然保留原始迭代器中的其余元素。
我知道这与take_while
的惰性实现不兼容,但仍然有用。这只是被判断为没有用到包含在标准库中,还是有其他一些我没有看到的问题?
答案 0 :(得分:17)
为了效率,所有迭代器适配器都按值取原始迭代器。此外,获得原始迭代器的所有权可以避免在没有必要时处理生命周期。
如果您希望保留对原始迭代器的访问权限,可以使用by_ref
。这引入了一个间接层,但程序员选择在需要该功能时选择额外的工作:
Warning: Attempt to present <xxx.ModifyCameraImageViewController: 0x145e3eb70> on <xxx.ViewController: 0x145d20a60> whose view is not in the window hierarchy!
有输出
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
丢失了?这是因为一旦4
选择了一个值并决定不使用它,那么它就无处可去&#34;将它放回去#34;。把它放回原来需要选择更多存储和慢速,而不是总是需要。
我已使用itertools crate来处理此类案件,特别是take_while_ref
。
答案 1 :(得分:0)
如果它变得太复杂,我们可能使用了错误的工具。
请注意,此处为 4。
fn main() {
let v = [1, 2, 3, 4, 5, 6, 7, 8];
let mut i1 = v.iter().peekable();
while let Some(z) = i1.next_if(|n| n < &&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
是的,OP 要求 take_while
和 Shepmaster's solution 非常棒。