Перейти к содержимому
Теория · Циклы · урок 3 из 8

break и continue

В прошлом уроке бегун бегал круги, пока условие не скажет «хватит». Но иногда бегун сходит с дорожки раньше: например, он ищет на трибунах друга и уходит, как только его увидел. Бегать дальше незачем.

Цикл, который что-то ищет, тоже должен остановиться, как только нашёл. Иначе он доходит до конца и проверяет числа, которые уже не нужны. Инструкция break завершает цикл сразу. Эта программа ищет первое число больше 50, которое делится на 7:

GO
package main

import "fmt"

func main() {
    for i := 51; i <= 100; i++ {
        if i%7 == 0 {
            fmt.Println(i) // 56
            break
        }
    }
}

Два способа прервать проход

Две инструкции внутри тела цикла меняют обычный ход итераций. Обе пишут отдельной строкой, чаще всего внутри if. Разница в том, что они прерывают.

break

break завершает весь цикл. Давайте пройдём по итерациям программы выше:

  1. Для 51–55 условие i%7 == 0 ложно, и цикл идёт дальше.
  2. На 56 условие истинно, и программа печатает 56.
  3. break уводит бегуна с дорожки: цикл завершён.

После break остаток тела и все следующие итерации пропускаются. Программа продолжается со строки после цикла. Без break эта программа напечатала бы все такие числа до 100: 56, 63, 70 и так далее до 98.

Где break встречается чаще всего:

  • в цикле поиска — чтобы остановиться на первой находке;
  • в бесконечном цикле for { … } — это обычный способ выйти, когда цель достигнута.

Если один цикл стоит в теле другого, break завершает только внутренний — тот, в теле которого он написан.

continue

Инструкция continue пропускает только остаток текущего прохода и переходит к следующей итерации. Цикл при этом не заканчивается. Бегун срезает остаток круга и сразу начинает следующий, а отметка в блокноте всё равно ставится. В цикле с тремя частями после continue выполняется шаг, а затем проверяется условие.

GO
for i := 1; i <= 6; i++ {
    if i%2 == 0 {
        continue
    }
    fmt.Print(i, " ") // 1 3 5
}

В отличие от Println, fmt.Print не ставит пробел между числом и строкой, поэтому разделитель — сама строка " ". Разберём, что происходит:

  1. Для 2, 4 и 6 условие i%2 == 0 истинно, и до fmt.Print дело не доходит.
  2. Программа печатает остальные числа: 1 3 5.
  3. Цикл доходит до 6, как и без continue.

Если заменить continue на break, программа напечатает только 1: цикл закончится на i, равной 2. continue удобен, когда неподходящие значения нужно пропустить, а остальные обработать.

Здесь картинка с блокнотом заканчивается. В цикле с одним условием шага в заголовке нет, и отметку за вас никто не поставит. Там измените переменную до continue, иначе следующий проход начнётся с тем же значением, и цикл не закончится.

Частая ошибка

break внутри switch, который стоит в цикле:

GO
for i := 1; i <= 5; i++ {
    switch i {
    case 3:
        break // ✗
    }
    fmt.Print(i)
}

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

  1. Перед циклом ставят метку — имя с двоеточием, например loop:.
  2. После break пишут это имя: break loop.
GO
loop:
for i := 1; i <= 5; i++ {
    switch i {
    case 3:
        break loop
    }
    fmt.Print(i) // 12
}

Теперь на i, равной 3, break loop завершает весь цикл, и программа печатает 12. Также метка помогает выйти сразу из двух вложенных циклов: break loop во внутреннем цикле завершает и внешний, перед которым она стоит. На собеседовании иногда спрашивают именно это: как выйти из цикла изнутри switch или из двух циклов сразу.

Главное

  • break завершает цикл сразу, и программа продолжается после него.
  • continue пропускает остаток прохода, а шаг цикла с тремя частями всё равно выполняется.
  • Внутри switch слово break завершает только switch; чтобы выйти из цикла, нужна метка: break loop.

Подпишись, чтобы пройти курс

Курс бесплатный. Войди через Telegram и подпишись на канал — откроются все уроки.

Войти другим способом