Как работает оператор break в цикле и какой будет вывод
Что проверяют
Знаете ли вы, из какой конструкции выходит break в Go, особенно когда он стоит внутри switch или select в цикле. Обычно дают короткий код и просят назвать вывод, а следом спрашивают про метки и continue.
Как отвечать
В Go один цикл, for, а break завершает самый внутренний for, switch или select, в котором стоит. Выполнение продолжается с первой инструкции после этой конструкции. Классический пример:
for i := 1; i <= 5; i++ {
if i == 3 {
break
}
fmt.Println(i)
}Вывод 1 и 2: на i == 3 цикл заканчивается до печати, а код после цикла выполняется как обычно.
Дальше то, что обычно и проверяют:
breakвнутриswitchв цикле: выходит только изswitch, цикл продолжается. В Gocaseне проваливается сам, для этого естьfallthrough, так чтоbreakвswitchнужен редко, и тем опаснее он внутри цикла;selectв цикле: вfor { select { ... } }breakв веткеcase <-ctx.Done():завершает толькоselect, цикл крутится дальше;- метки:
break Outerвыходит из конструкции, помеченнойOuter:, так выходят сразу из вложенных циклов. Метка ставится на самfor,switchилиselect; continue: переходит к следующей итерации, вforс тремя выражениями сначала выполнивi++.
Для задач на вывод помните и соседнюю тему: с Go 1.22 переменная цикла создаётся заново на каждой итерации, и замыкания с горутинами больше не видят одно общее последнее значение.
Где спотыкаются
Ставят break в select внутри бесконечного цикла, ожидая выхода, и получают горутину, которая не завершается. Нужна метка или return.
Путают назначение меток. Без метки break выходит из внутренней конструкции, метка нужна именно для выхода из внешней.
Думают, что break Outer перезапускает внешний цикл, как goto на метку. Выполнение продолжается после помеченной конструкции.