嵌套迭代器的循环

nja*_*ard 4 rust

如您所知,for in如果直接向循环传递迭代器,则循环在循环持续时间内拥有其迭代器,如下所示:

let v = vec![...];
let mut i = v.iter();
for _ in i { }
Run Code Online (Sandbox Code Playgroud)

正如 malbarbo 所观察到的,您可以通过编写 来指示for引用。但是,您不能在 for 循环内部重复该操作:ii.by_ref()

for _ in i.by_ref() {
    for _ in i.by_ref() {
          // ^ error: cannot borrow `i` as mutable
          // more than once at a time [--explain E0499]
        break;
    }
}
Run Code Online (Sandbox Code Playgroud)

可以理解的是,外部for循环必须修改其迭代器,因此它需要对其进行可变引用,并且其他人不能再调用可变方法i。我们可以更直接地展示这个问题,如下所示:

for _ in i.by_ref() {
    i.next(); // same error
}
Run Code Online (Sandbox Code Playgroud)

一种办法是制作外部foraloopi.next()直接调用。有没有更漂亮的方法来获得我们的蛋糕(外部 for 循环迭代i)并吃掉它(我们仍然可以i在外部循环内部前进)?

Lin*_*ope 5

这可以使用while let表达式来实现。

let x = vec![1, 2, 3, 5, 4, 6, 7, 5, 8, 5];

let mut i = x.iter();
while let Some(v) = i.next() {
    println!("First before inner loop: {}", v);
    for v in i.by_ref() {
        if *v == 5 {
            println!("Found a 5");
            break;
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

操场

while let Some(v) = i.next()或多或少直接相当于“不借用迭代器的for循环”。反过来,它本质上就是:

loop {
    match i.next() {
        Some(v) => { loop_body },
        _ => { break; },
    };
}
Run Code Online (Sandbox Code Playgroud)

额外的好处:您可以while let在几乎任何您想重复调用的返回总和类型的其他表达式上使用。