为什么Iterator :: take_while取得迭代器的所有权?

时间:2015-07-13 00:48:51

标签: rust

我发现奇怪的是Iterator::take_while取得了迭代器的所有权。它似乎是一个有用的功能,能够使第一个 x 元素满足某些功能,但仍然保留原始迭代器中的其余元素。

我知道这与take_while的惰性实现不兼容,但仍然有用。这只是被判断为没有用到包含在标准库中,还是有其他一些我没有看到的问题?

2 个答案:

答案 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_whileShepmaster's solution 非常棒。