Switch и fallthrough в Go: разбор, который экономит часы
Конструкция switch в Go работает не так, как в C-подобных языках. Разбираем, почему она не проваливается по умолчанию, когда fallthrough оправдан и где новички теряют состояние предыдущего кейса.
В Go конструкция switch — это не просто «красивый if». Она работает иначе, чем в C-подобных языках: по умолчанию не проваливается в следующий кейс, а позволяет описывать выражения целыми блоками. Разберём, как это устроено, и где имеет смысл вернуть «провал» обратно через fallthrough.
Базовый синтаксис
Switch в Go бывает двух видов: с выражением и без. Чаще всего вы будете писать первый вариант — он напоминает классический switch, но без подводных камней с проваливанием:
switch status {
case "active":
fmt.Println("в работе")
case "done", "approved": // несколько значений в одном case
fmt.Println("готово")
default:
fmt.Println("неизвестный статус")
}В Go нет неявного break — он не нужен. После выполнения тела case управление сразу выходит из switch.
Когда нужен fallthrough
Иногда «провал» в следующий case — это именно то, что вы хотите. Чаще всего — в декларативных таблицах состояний или при последовательной обработке этапов. В Go провал нужно явно запросить:
switch step {
case "review":
notify(mentor)
fallthrough // → выполнится и тело "log"
case "log":
audit.Append(step)
case "done":
archive(step)
}fallthrough не проверяет условие следующего case — он просто выполняет его тело. Это самая частая ошибка новичков.
Type switch
Отдельный вид — switch по типу интерфейса. Незаменим, когда работаете с any или с собственными интерфейсами:
switch v := value.(type) {
case int:
fmt.Println("целое:", v)
case string:
fmt.Println("строка:", v)
default:
fmt.Printf("другой тип: %T\n", v)
}Краткая сводка
| Конструкция | По умолчанию | Когда применять |
|---|---|---|
switch x | break после кейса | сравнение значения |
switch {} | break после кейса | цепочка условий |
x.(type) | break после кейса | работа с интерфейсами |
fallthrough | выполняет следующий case | табличные сценарии |