Перейти к основному содержимому
  1. Rust/

Циклы и диапазоны в Rust

1120 слов·6 минут· loading · loading · · ·Rust-basic
about-rust - Эта статья часть цикла.
Статей прочитано 0/36
0%
📚 Введение и дополнительные материалы
🟢 Начальный уровень (Rust-basic)
Не прочитана
05 Циклы и диапазоны в Rust (текущая)
Не прочитана
Не прочитана
Не прочитана
Не прочитана
Не прочитана

Введение
#

В языке Rust есть три основных вида циклов: while, loop и for. Для управления итерациями используются стандартные операторы:

  • break — немедленно прерывает выполнение цикла.
  • continue — пропускает оставшуюся часть тела цикла и переходит к следующей итерации.

Давайте детально рассмотрим все виды циклов, способы обхода коллекций и работу с метками на интерактивных слайдах:

Циклы в Rust
Шаг 1/3
 1fn main() {
 2    let mut n = 0;
 3    // Цикл while
 4    while n < 3 {
 5        println!("while: n = {}", n);
 6        n += 1;
 7    }
 8
 9    // Цикл loop с возвратом значения через break
10    let mut counter = 0;
11    let result = loop {
12        counter += 1;
13        if counter == 5 {
14            break counter * 2; // Возвращает 10 из цикла loop
15        }
16    };
17    println!("Результат loop: {}", result);
18
19    // Симуляция do-while через loop
20    let mut x = 0;
21    loop {
22        x += 1;
23        println!("do-while: x = {}", x);
24        if x >= 3 {
25            break;
26        }
27    }
28}

Циклы while, loop и возврат значений

  • while выполняет тело, пока истинно логическое условие.
  • loop представляет собой бесконечный цикл.
  • Выражение loop может возвращать значение наружу: для этого нужно указать его после оператора break.
  • Отсутствующий в Rust цикл do-while можно сымитировать проверкой условия выхода в конце бесконечного loop.

Виды циклов в Rust
#

1. Цикл while
#

Выполняет тело цикла до тех пор, пока условие истинно (true).

let mut n = 0;
while n < 10 {
    foo(n);
    n += 1;
}

2. Цикл while let
#

Повторяет выполнение цикла, пока выражение успешно сопоставляется с шаблоном (например, для разбора Option или Result).

// Цикл работает, пока foo() возвращает Some(x)
while let Some(x) = foo() {
    bar(x);
}

3. Цикл loop и возврат значений
#

Бесконечный цикл, который выполняется до тех пор, пока не будет встречен явный оператор break.

  • Использование как выражения: loop может возвращать значение через оператор break. Это значение можно присвоить переменной.
let event = loop {
    let event = get_event();
    if let Some(e) = event {
        break e; // Возвращает значение e из цикла loop
    }
};

4. Реализация цикла do ... while
#

В Rust нет встроенного ключевого слова do-while. Его поведение можно сымитировать двумя способами:

  1. Через бесконечный loop и проверку условия в конце:
loop {
    let x = foo();
    if x == 0 { break; }
}
  1. Используя блок кода в качестве условия цикла while:
while {
    let x = foo();
    x != 0 // Условие продолжения цикла
} {} // Пустое тело цикла

Диапазоны (Ranges) и цикл for
#

Типы диапазонов (Range Types)
#

Диапазоны представляют собой структуры из модуля std::ops. Нижняя граница (если она указана) всегда включается в диапазон.

СинтаксисОписание типаВключение границВнутреннее представление
..Неограниченный диапазонНет границRangeFull
..10Ограниченный сверху диапазонИсключая верхнюю границу (0-9)RangeTo
..=10Ограниченный сверху диапазон, включительноВключая верхнюю границу (0-10)RangeToInclusive
0..Ограниченный снизу диапазонОт 0 до бесконечностиRangeFrom
0..10Ограниченный диапазонВключая 0, исключая 10 (0-9)Range
0..=10Ограниченный диапазон, включительноВключая обе границы 0 и 10 (0-10)RangeInclusive

Пример: Цикл for n in 1..10 выполнится ровно 9 раз (для значений от 1 до 9 включительно).

Анатомия цикла for
#

Цикл for используется для итерации по элементам коллекции или диапазона.

  • Требование к типу: Выражение справа от in обязано реализовывать типаж std::iter::IntoIterator.

В зависимости от необходимости владения данными или ссылками, применяются разные подходы:

  1. Потребление коллекции (Move): for item in arr { ... } (неявно вызывает arr.into_iter()).
  2. Итерация по разделяемым ссылкам (&T): for item in &arr { ... } (неявно вызывает (&arr).into_iter()).
  3. Итерация по изменяемым ссылкам (&mut T): for item in &mut arr { ... } (неявно вызывает (&mut arr).into_iter()).

Получение индекса при итерации (.enumerate())
#

Для одновременного получения индекса элемента и самого элемента используется метод .enumerate(), который возвращает кортеж вида (index, item).

let arr: [u8; 3] = [10, 20, 30];
for (idx, item) in arr.into_iter().enumerate() {
    println!("{idx}: {item}");
}

Метки циклов и блоков (Labels)
#

Метки позволяют управлять выполнением конкретного внешнего цикла или блока изнутри вложенных структур. Названия меток всегда начинаются с одиночной кавычки (апострофа), например: 'label.

Метки в циклах
#

Применяются для выхода из внешнего цикла при нахождении во вложенном.

'outer: loop {
    'inner: loop {
        if need_exit() {
            break 'outer; // Полный выход из внешнего цикла
        }
    }
}

Метки в именованных блоках кода
#

Обычные блоки кода { ... } также могут иметь метки. Это позволяет досрочно прерывать выполнение текущего блока и возвращать значение во внешнюю переменную с помощью break.

let y = 'tag: {
    let x = foo();
    if x < 0 {
        break 'tag 0; // Досрочный выход из блока с возвратом значения 0
    }
    x
};

Ограничение компилятора: Оператор break без указания явной метки внутри обычного обособленного блока кода (не являющегося циклом) вызовет ошибку компиляции.


Проверь свои знания!
#

Пройдите короткий интерактивный тест, чтобы закрепить понимание циклов в Rust.

История обновлений

  • Добавил интерактивные слайды и тесты по циклам, диапазонам и меткам.
Статья прочитана
Пожалуйста, оцените насколько статья была вам полезна и понятна
Цикл статей
about-rust - Эта статья часть цикла.
Статей прочитано 0/36
0%
📚 Введение и дополнительные материалы
🟢 Начальный уровень (Rust-basic)
Не прочитана
05 Циклы и диапазоны в Rust (текущая)
Не прочитана
Не прочитана
Не прочитана
Не прочитана
Не прочитана

Связанные статьи

Hash Map в Rust

·962 слова·5 минут· loading · loading ·Rust-basic