如您所知,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)
一种办法是制作外部foraloop并i.next()直接调用。有没有更漂亮的方法来获得我们的蛋糕(外部 for 循环迭代i)并吃掉它(我们仍然可以i在外部循环内部前进)?
这可以使用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在几乎任何您想重复调用的返回总和类型的其他表达式上使用。