while let
Так же, как иif let
, while let
может сделать неудобный match
более терпимым. Рассмотрим следующий пример, в котором мы увеличиваем значение i
:
#![allow(unused)] fn main() { // Создадим переменную `optional` с типом `Option<i32>` let mut optional = Some(0); // Неоднократно повторим наш тест. loop { match optional { // Если `optional` деструктурируется, выполним следующий блок. Some(i) => { if i > 9 { println!("Больше 9, уходим отсюда!"); optional = None; } else { println!("`i` равен `{:?}`. Попробуем еще раз.", i); optional = Some(i + 1); } // ^ Требует 3 уровня вложенности! }, // Выходим из цикла в случае ошибки деструктуризации: _ => { break; } // ^ Зачем это нужно? Должен быть способ сделать это лучше! } } }
Использование while let
делает этот пример намного приятнее:
fn main() { // Создадим переменную `optional` с типом `Option<i32>` let mut optional = Some(0); // Это можно прочитать так: "Пока `let` деструктурирует `optional` в // `Some(i)`, выполняем блок (`{}`). В противном случае `break`. while let Some(i) = optional { if i > 9 { println!("Больше 9, уходим отсюда!"); optional = None; } else { println!("`i` равен `{:?}`. Попробуем ещё раз.", i); optional = Some(i + 1); } // ^ Меньше смещаемся вправо, к тому же // нет необходимости обрабатывать ошибки. } // ^ К `if let` можно добавить дополнительный блок `else`/`else if` // Для `while let` подобного нет. }