Поиск…
Синтаксис
loop { block } // бесконечный цикл
а условие { block }
а пусть pattern = expr { block }
для шаблона в expr { block } // expr должен реализовать IntoIterator
continue // перейти к концу тела цикла, при необходимости начать новую итерацию
break // остановить цикл
' label : loop { block }
' label : while условие { block }
' label : while let pattern = expr { block }
' label : для шаблона в expr { block }
продолжить 'метки // переход к концу меченой этикетки тела цикла, начиная с новой итерацией в случае необходимости
метка BREAK '// остановить метку цикла меченого
основы
В Rust есть 4 петлевые конструкции. Все приведенные ниже примеры дают одинаковый результат.
Бесконечные петли
let mut x = 0;
loop {
if x > 3 { break; }
println!("{}", x);
x += 1;
}
В то время как петли
let mut x = 0;
while x <= 3 {
println!("{}", x);
x += 1;
}
Также смотрите: В чем разница между loop и while true ?
Циклы, совпадающие с шаблонами
Они иногда известны как while let петлям для краткости.
let mut x = Some(0);
while let Some(v) = x {
println!("{}", v);
x = if v < 3 { Some(v + 1) }
else { None };
}
Это эквивалентно match внутри блока loop :
let mut x = Some(0);
loop {
match x {
Some(v) => {
println!("{}", v);
x = if v < 3 { Some(v + 1) }
else { None };
}
_ => break,
}
}
Для циклов
В Rust for цикла может использоваться только с «итерируемым» объектом (т.е. он должен реализовывать IntoIterator ).
for x in 0..4 {
println!("{}", x);
}
Это эквивалентно следующему фрагменту, включая while let :
let mut iter = (0..4).into_iter();
while let Some(v) = iter.next() {
println!("{}", v);
}
Примечание: 0..4 возвращает объект Range который уже реализует свойство Iterator . Поэтому into_iter() не является необходимым, но сохраняется только для иллюстрации того, что for делает. IntoIterator обзор см. В официальных документах for циклов и IntoIterator .
См. Также: Итераторы
Подробнее о циклах
Как уже упоминалось в «Основах», мы можем использовать все, что реализует IntoIterator с циклом for :
let vector = vec!["foo", "bar", "baz"]; // vectors implement IntoIterator
for val in vector {
println!("{}", val);
}
Ожидаемый результат:
foo
bar
baz
Обратите внимание, что итерация по vector таким образом потребляет его (после цикла for vector не может использоваться снова). Это связано с тем, что IntoIterator::into_iter движется self .
IntoIterator также реализуется с помощью &Vec<T> и &mut Vec<T> (выводя значения с типами &T и &mut T соответственно), поэтому вы можете предотвратить перемещение vector , просто передав его по ссылке:
let vector = vec!["foo", "bar", "baz"];
for val in &vector {
println!("{}", val);
}
println!("{:?}", vector);
Заметим, что val имеет тип &&str , так как vector имеет тип Vec<&str> .
Управление петлей
Все петлевые конструкции позволяют использовать выражения break и continue . Они воздействуют на ближайшую окружную (самую внутреннюю) петлю.
Управление базовым контуром
break завершает цикл:
for x in 0..5 {
if x > 2 { break; }
println!("{}", x);
}
Выход 0
1
2
continue завершение текущей итерации раньше
for x in 0..5 {
if x < 2 { continue; }
println!("{}", x);
}
Выход 2
3
4
Управление расширенным контуром
Теперь предположим, что у нас есть вложенные петли и мы хотим break во внешний цикл. Затем мы можем использовать метки меток, чтобы указать, к какому циклу относится break или continue . В следующем примере 'outer - это метка, присвоенная внешнему циклу.
'outer: for i in 0..4 {
for j in i..i+2 {
println!("{} {}", i, j);
if i > 1 {
continue 'outer;
}
}
println!("--");
}
Выход 0 0
0 1
--
1 1
1 2
--
2 2
3 3
При i > 1 внутренний цикл повторялся только один раз и -- не печатался.
Примечание. Не путайте метку цикла с переменной времени жизни. Постоянные переменные встречаются только рядом с & или как общий параметр внутри <> .