2016-08-05 108 views
3

如你所知,如果你直接將它傳遞一個迭代器,像這樣一個for in環路擁有其循環的持續時間迭代器:嵌套一個迭代的循環

let v = vec![...]; 
let mut i = v.iter(); 
for _ in i { } 

由於malbarbo觀察,可以指示for到通過編寫i.by_ref()參考i。但是,你不能重複,從裏面的for循環:

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; 
    } 
} 

理解的是,外for循環必須修改它的迭代器,所以它需要一個可變引用它,而不是別人可以調用i可變的方法了。我們可以更直接地表明這個問題就像這樣:

for _ in i.by_ref() { 
    i.next(); // same error 
} 

一個辦法是使外for一個loop並直接調用i.next()。有沒有更漂亮的方式讓我們的蛋糕(外循環迭代i)並且也吃了(我們仍然可以在外循環內部提前i)?

回答

3

這是可行的,使用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; 
     } 
    } 
} 

Playground

while let Some(v) = i.next()是或多或少直接等同於 「在沒有借用迭代循環」。這,反過來,實際上只是:

loop { 
    match i.next() { 
     Some(v) => { loop_body }, 
     _ => { break; }, 
    }; 
} 

獎勵:你可以在幾乎要反覆調用返回之類的任何其他表達式中使用while let