Потік контролю Let

Rust має кілька конструкцій потоку керування, які відрізняються від інших мов. Вони використовуються для зіставлення шаблонів:

  • вирази if let
  • вирази let else
  • вирази while let

вирази if let

Вираз if let дозволяє виконувати інший код залежно від того, чи відповідає значення шаблону :

XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX

вирази let else

Для загального випадку зіставлення шаблону і повернення з функції використовуйте let else. Випадок “else” повинен відрізнятися (return, break або паніка - що завгодно, але не випадання з кінця блоку).

XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX

Подібно до if let, існує варіант while let, який багаторазово перевіряє значення на відповідність шаблону:

XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX

Тут String::pop повертає Some(c) поки рядок не стане порожнім, після чого поверне None. Використання while let дозволяє нам продовжувати ітерацію по всіх елементах.

Speaker Notes

This slide should take about 10 minutes.

if-let

  • На відміну від match, if let не має охоплювати всі гілки. Це може зробити його більш лаконічним, ніж match.
  • Загальним використанням є обробка значень Some під час роботи з Option.
  • На відміну від match, if let не підтримує захисні вирази для збігу шаблонів.

let-else

if-let може накопичуватись, як показано. Конструкція let-else підтримує згладжування цього вкладеного коду. Перепишіть незручну версію для студентів, щоб вони могли побачити перетворення.

Переписана версія така:

#![allow(unused)] fn main() { fn hex_or_die_trying(maybe_string: Option<String>) -> Result<u32, String> { let Some(s) = maybe_string else { return Err(String::from("отримав None")); }; let Some(first_byte_char) = s.chars().next() else { return Err(String::from("отримав порожній рядок")); }; let Some(digit) = first_byte_char.to_digit(16) else { return Err(String::from("не шістнадцяткова цифра")); }; return Ok(digit); } }

while-let

  • Зверніть увагу, що цикл while let триватиме, доки значення відповідає шаблону.
  • Ви можете переписати цикл while let як нескінченний цикл з оператором if, який переривається, коли для name.pop() немає значення для розгортання. Цикл while let забезпечує синтаксичний цукор для наведеного вище сценарію.