JavaRush /Курсы /Swift SELF /Управление циклом — break, continue

Управление циклом — break, continue

Swift SELF
4 уровень , 3 лекция
Открыта

1. Зачем управлять циклом

Когда вы только начинаете писать циклы, хочется, чтобы они были «честными»: for идёт до конца диапазона, while крутится, пока условие истинно, и всё максимально предсказуемо. И это правильный этап. Но довольно быстро вы встречаете жизненные ситуации, где «дойти до конца» не нужно — вы уже нашли ответ, вам достаточно первых данных, или пользователь попросил остановиться.

Вот здесь и появляются два ключевых инструмента управления потоком внутри цикла: break и continue. Они звучат как названия рок-групп (особенно break), но на деле это очень практичные команды.

Важно: break и continue — не «читерство» и не «грязный хак». Это нормальная часть языка, и в реальном Swift‑коде вы их будете видеть постоянно. Например, паттерн while true { ... if ... { break } } — вполне официальный стиль: цикл крутится «вечно», но имеет чёткое правило остановки через break.

2. break: выходим из цикла

break нужен, когда вы хотите немедленно завершить цикл, в котором он написан. То есть «прямо сейчас перестать повторять и перейти к коду после цикла». Это похоже на ситуацию, когда вы ищете ключи в кармане: нашли — и дальше карман проверять уже не надо.

Минимальный пример: досрочно остановить for

После этого подзаголовка будет очень простой пример, чтобы вы почувствовали механику. Не пытайтесь сразу искать в нём «пользу для человечества» — это тренировочная площадка, где мы наблюдаем поведение программы глазами.

let n = 10

for i in 1...n {
    if i == 4 {
        print("Нашли 4 — выходим")
        break
    }
    print("i=\(i)")
}
print("После цикла")

Здесь цикл мог бы напечатать i=1 до i=10, но мы «рубим» его на условии i == 4. В результате диапазон i=5...10 уже не выполняется.

Типовой сценарий: поиск первого подходящего

Теперь подойдём ближе к реальности. Частая задача: найти первое число, которое подходит условию. Как только нашли — смысла продолжать нет. В таких случаях break превращает цикл из «проверю всё подряд» в «проверю, пока не найду».

let target = 21
var firstDivisor = 0

for d in 2...target {
    if target % d == 0 {
        firstDivisor = d
        break
    }
}

print("firstDivisor=\(firstDivisor)") // firstDivisor=3

Мы нашли делитель и остановились на первом же. Это и есть «ранний выход» — в хорошем смысле.

break в while: пока не скажу «стоп»

После этого подзаголовка важно поймать одну мысль: break особенно полезен там, где цикл может продолжаться неопределённо долго, потому что зависит от ввода пользователя. И тогда break становится явным «контрактом остановки» — вы пишете в коде, при каком событии цикл заканчивается.

var sum = 0

while true {
    let line = readLine() ?? ""
    if line == "stop" {
        break
    }

    let value = Int(line) ?? 0
    sum = sum + value
}

print("sum=\(sum)")

Это тот самый паттерн «вечный цикл + правило остановки». Важная деталь: правило остановки должно быть очевидным и находиться прямо рядом с чтением/логикой. Тогда такой код читается нормально и не вызывает ощущения «программа ушла в астрал». В Swift‑сообществе этот стиль вполне привычен.

3. continue: пропускаем итерацию и идём дальше

Если break — это «закрываем цикл целиком», то continue — это «пропускаем только текущую итерацию». Представьте очередь на кассе: человек перед вами забыл кошелёк и ушёл за ним — очередь не отменяется, просто этот человек временно «пропущен», а вы двигаетесь дальше.

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

Минимальный пример: печатаем только нечётные

После этого подзаголовка пример будет максимально «школьный», но он идеально показывает механику: часть значений мы «отбрасываем», и код ниже continue на этой итерации не выполняется.

for i in 1...10 {
    if i % 2 == 0 {
        continue
    }
    print("odd=\(i)")
}

Все чётные числа «проскальзывают» мимо print.

Типовой сценарий: фильтрация в цикле

После этого подзаголовка мы применим continue к вводу пользователя — это более жизненно. Часто человек вводит пустую строку, случайно пробел, или вообще «что-то не то». И вместо того чтобы писать огромную вложенность if/else, удобнее сказать: «если мусор — пропусти итерацию и попроси ввод снова».

var count = 0

while true {
    let line = readLine() ?? ""

    if line == "stop" {
        break
    }

    if line == "" {
        continue
    }

    let value = Int(line) ?? 0
    if value <= 0 {
        continue
    }

    count = count + 1
    print("accepted=\(value)") // accepted=...
}

print("count=\(count)")

Тут continue работает как «сито»: пустые строки и неположительные числа не участвуют в «нормальной» логике.

4. Таблица-памятка: break vs continue

В этом месте полезно притормозить и зафиксировать различия. Когда вы пишете программу, мозг часто путает «прервать итерацию» и «прервать цикл». Из-за этого появляются баги, которые выглядят как «почему оно не работает, я же написал continue?!».

Команда Что делает Куда прыгаем дальше
break
завершает весь ближайший цикл к строке после цикла
continue
завершает текущую итерацию к следующей итерации (или к проверке условия в while)

Если вам нужно «закончить прямо сейчас и выйти наружу» — это break. Если нужно «пропустить текущий шаг и попробовать следующий» — это continue.

5. Мини‑проект: «Копилка расходов»

Сейчас мы соберём маленькую консольную программу, которую будем «выращивать» из нескольких примеров. Она простая, но полезная: пользователь вводит расходы (целые числа), программа считает сумму и количество принятых значений. Команда "stop" завершает ввод. Пустые строки и мусор мы игнорируем.

Важно: мы сознательно держимся в рамках того, что вы уже знаете. Никаких функций (func), никаких массивов, никакого switch. Только ввод, условия, циклы и аккуратные проверки.

Версия 1: только break по команде "stop"

После этого подзаголовка будет «скелет» программы: цикл чтения, выход по слову "stop", суммирование всего остального. Это самый простой вариант, он нужен, чтобы не смешивать сразу всё.

var total = 0

while true {
    let line = readLine() ?? ""
    if line == "stop" {
        break
    }

    let value = Int(line) ?? 0
    total = total + value
}

print("total=\(total)")

Да, здесь есть «слабое место»: если введут "hello", оно превратится в 0 и всё равно попадёт в сумму. Сейчас исправим.

Версия 2: добавляем continue как валидацию ввода

Сейчас сделаем поведение более человечным: пустые строки, нули и отрицательные числа не считаем расходами (представим, что пользователь ошибся). А ещё выведем подсказку, если ввод некорректный — но так, чтобы не усложнять код.

var total = 0
var acceptedCount = 0

while true {
    let line = readLine() ?? ""

    if line == "stop" {
        break
    }

    if line == "" {
        print("Пустая строка — пропускаю")
        continue
    }

    let value = Int(line)
    if value == nil {
        print("Это не число — пропускаю")
        continue
    }

    let amount = value ?? 0
    if amount <= 0 {
        print("Нужно положительное число — пропускаю")
        continue
    }

    total = total + amount
    acceptedCount = acceptedCount + 1
}

print("acceptedCount=\(acceptedCount)")
print("total=\(total)")

Обратите внимание на стиль: как только мы понимаем, что строка «плохая», мы делаем continue и не держим в голове огромную лестницу else if else if else.

6. Типовые паттерны, которые стоит узнавать

Сейчас будет серия маленьких сценариев. Каждый из них — как мини-кирпичик. По отдельности они выглядят простыми, но потом из них строятся вполне серьёзные программы.

Пока не введут корректно: repeat-while + continue

Здесь важно не устроить путаницу: continue работает и в repeat-while, но новичкам иногда сложно «поймать», что условие проверится после тела. Поэтому пример будет очень осторожный: мы делаем минимум логики и явно показываем, что происходит.

var number = 0

repeat {
    let line = readLine() ?? ""
    let value = Int(line) ?? 0

    if value <= 0 {
        print("Введите число > 0")
        continue
    }

    number = value
} while number <= 0

print("number=\(number)")

Тут continue означает: «показали сообщение и пошли на следующий круг». А условие while number <= 0 всё равно проверится (потому что это repeat-while).

Показали "help" и вернулись к началу

Сейчас добавим в нашу «копилку расходов» маленькую команду "help". Это частая вещь в интерактивных программах: пользователь вводит слово-команду, программа печатает подсказку и продолжает цикл, не пытаясь превращать "help" в число.

var total = 0

while true {
    let line = readLine() ?? ""

    if line == "stop" {
        break
    }

    if line == "help" {
        print("Введите расход целым числом. stop — завершить.")
        continue
    }

    let amount = Int(line) ?? 0
    total = total + amount
}

print("total=\(total)")

Да, мы всё ещё не валидируем "hello" — это упрощённая версия ради паттерна. В реальной версии мы бы объединили "help" и проверки из предыдущего раздела.

Ограничение по условию: выходим, если достигли лимита

Сейчас пример про break, который встречается постоянно: мы копим сумму, но как только она стала слишком большой (или достигла цели) — выходим.

let goal = 1000
var total = 0

while true {
    let line = readLine() ?? ""
    if line == "stop" { break }

    let amount = Int(line) ?? 0
    if amount <= 0 { continue }

    total = total + amount
    print("total=\(total)")

    if total >= goal {
        print("Цель достигнута!")
        break
    }
}

7. Полезные нюансы и ментальные модели

Визуальная схема: как читать код с continue

После этого подзаголовка — маленькая блок-схема, чтобы мозг перестал воспринимать continue как «магическую телепортацию». На самом деле всё просто: если continue сработал — остальной код в теле цикла на этой итерации не выполняется.

псевдокод/схема:

flowchart TD
    A[Начало итерации] --> B{Условие 'плохой ввод'?}
    B -- да --> C[continue] --> D[Следующая итерация]
    B -- нет --> E[Основная логика] --> F[Конец итерации] --> D

Такой рисунок полезно вспоминать, когда вам кажется: «я же увеличиваю сумму… почему она не увеличилась?» — очень часто ответ: «потому что перед этим сработал continue».

Нюанс читаемости: continue уменьшает вложенность

Сейчас важная инженерная мысль. Когда вы пишете код в стиле:

if good {
    // много кода
}

и у вас пять проверок подряд, вы быстро получаете «пирамиду» из вложенных if. Читать это тяжело: взгляд постоянно ищет, где закрывается какой блок.

continue позволяет писать наоборот: «если плохо — пропусти», а «нормальная логика» остаётся на одном уровне вложенности. В Swift‑сообществе даже обсуждали, что некоторые синтаксические формы фильтрации в цикле по смыслу сводятся к continue (то есть «не подходит — пропускаем»).

Мы не будем использовать редкие синтаксические трюки, но идея полезная: continue — это инструмент, который делает код плоским и легче читаемым.

for + continue: пропуск мусора

Здесь мы вернёмся к for-in и покажем типовой сценарий: мы делаем фиксированное число повторов (например, 5 вводов), но часть вводов может оказаться некорректной. В этом случае continue позволяет «не засчитывать» некорректную итерацию? Осторожно: нет, continue не отменяет сам факт итерации for. Он просто пропускает код ниже.

Это важно: если вам нужно «сделать ровно 5 корректных вводов», то for может быть неудобен — тогда лучше while со счётчиком корректных значений. Но в рамках примера мы покажем именно поведение.

var total = 0

for _ in 0..<5 {
    let line = readLine() ?? ""
    let value = Int(line) ?? 0

    if value <= 0 {
        print("Не засчитываю")
        continue
    }

    total = total + value
}

print("total=\(total)")

8. Типичные ошибки при работе с break и continue

Ошибка №1: ожидать, что continue завершит цикл целиком.
Это очень частая путаница: человек пишет continue, думая «всё, выходим», а программа продолжает спрашивать ввод. Так и должно быть: continue завершает только текущую итерацию. Если нужно выйти насовсем — используйте break.

Ошибка №2: писать важный код после continue и удивляться, что он не выполняется.
Если у вас внизу тела цикла стоит total = total + amount, а выше есть continue, то при срабатывании continue сумма не изменится. Это не баг языка — это ваш «ранний прыжок». Хороший приём — держать continue ближе к началу итерации, как фильтры/валидацию, а «главную логику» — ниже.

Ошибка №3: делать while true, но забывать про правило остановки.
Сам по себе while true не плох. Он плох, когда вы не оставили читателю понятного способа выйти. Если в теле цикла нет гарантированного условия break, программа превращается в бесконечную. В хороших примерах break всегда рядом с чтением ввода или проверкой ключевого условия.

Ошибка №4: пытаться “починить” неправильное условие в while с помощью break.
Иногда пишут условие цикла слишком сложно, а потом добавляют break, чтобы «как-то работало». Лучше наоборот: либо делайте простое условие while, либо честно используйте while true и одно-два ясных правила break. Если и условие сложное, и breakов много — код становится трудным для проверки глазами.

Ошибка №5: “тихий” некорректный ввод без сообщений.
Технически можно молча делать continue на плохом вводе, но новичку (и пользователю) потом сложно понять, что произошло: «я ввёл что-то, а программа как будто проигнорировала». Часто помогает хотя бы короткое сообщение print("Некорректный ввод"). Это не обязательно всегда, но на этапе обучения — почти спасательный круг.

1
Задача
Swift SELF, 4 уровень, 3 лекция
Недоступна
Первый фактор
Первый фактор
1
Задача
Swift SELF, 4 уровень, 3 лекция
Недоступна
Печать без четырёх
Печать без четырёх
1
Задача
Swift SELF, 4 уровень, 3 лекция
Недоступна
Терминал ввода
Терминал ввода
1
Задача
Swift SELF, 4 уровень, 3 лекция
Недоступна
Лимит бюджета
Лимит бюджета
Комментарии
ЧТОБЫ ПОСМОТРЕТЬ ВСЕ КОММЕНТАРИИ ИЛИ ОСТАВИТЬ КОММЕНТАРИЙ,
ПЕРЕЙДИТЕ В ПОЛНУЮ ВЕРСИЮ