Операторы ветвления Switch-Case в Golang

GolangBeginner
Практиковаться сейчас

Введение

В предыдущей лабораторной работе мы изучили использование операторов ветвления if-else. В этой работе мы познакомимся с операторами switch-case. По сравнению с if-else, оператор switch лучше подходит для сценариев с множественным выбором условий.

Основные темы:

  • Операторы switch-case
  • Ключевое слово default
  • Ключевое слово fallthrough

Базовый синтаксис

Синтаксис оператора ветвления switch во многом похож на if, так как оба они основаны на проверке условий. Базовая структура выглядит следующим образом:

switch condition {
    case val1:
        // блок кода
    case val2:
        // блок кода
    ...
    default:
        // блок кода
}

В качестве условия (condition) может выступать выражение любого типа. Когда значение условия совпадает со значением в одном из блоков case, выполняется соответствующий код, после чего программа выходит из текущей ветки switch.

Важно помнить, что значения в блоках case должны иметь тот же тип, что и выражение в условии.

Программа проверяет блоки case сверху вниз и выполняет первый же совпавший вариант. После завершения выполнения этого блока работа с текущим switch прекращается.

Блок default аналогичен блоку else. Он выполняется в том случае, если ни один из предложенных case не подошел под условие.

Рассмотрим пример с прогнозом погоды. Создайте новый файл с именем switch.go и напишите в нем следующий код:

cd ~/project
touch switch.go
package main

import (
    "fmt"
)

func main() {
    // Погода на сегодня
    weather := "rainy"
    switch weather {
    case "snow":
        fmt.Println("Remember to wear a scarf today.🧣")
    case "rainy":
        fmt.Println("Remember to bring an umbrella today.🌂")
    default:
        fmt.Println("Today is sunny.☀")
    }
}

Запустите код:

go run switch.go

Результат будет следующим:

Remember to bring an umbrella today.🌂

Этот «прогноз погоды» выдает разные рекомендации в зависимости от условий. Сначала мы установили переменную погоды как "rainy" (дождливо). В конструкции switch-case мы предусмотрели три варианта: если идет снег — надеть шарф, если дождь — взять зонт, а во всех остальных случаях считать день солнечным.

Несколько значений в одной ветке

Один блок case может содержать сразу несколько значений, перечисленных через запятую:

switch condition {
    case val1, val2:
        // блок кода
    ...
}

Обновим нашу программу погоды следующим образом:

package main

import (
    "fmt"
)

func main() {
    // Погода на сегодня
    weather := "snow"
    switch weather {
    case "snow", "stormy":
        fmt.Println("Remember to wear a scarf today.🧣")
    case "haze", "sandstorm":
        fmt.Println("Remember to wear a mask today.😷")
    case "rainy":
        fmt.Println("Remember to bring an umbrella today.🌂")
    default:
        fmt.Println("Today is sunny.☀")
    }
}
go run switch.go

После запуска программы вы увидите:

Remember to wear a scarf today.🧣

Мы расширили список условий: теперь, например, при тумане или песчаной буре программа посоветует надеть маску.

Оператор switch без условной переменной

Условная переменная в операторе switch является необязательным параметром. Если ее опустить, switch будет работать аналогично цепочке if-else.

Перепишем программу для определения текущего дня недели, используя switch без переменной в заголовке:

package main

import (
    "fmt"
    "time"
)

func main() {
    today := time.Now().Weekday()
    switch {
    case today == time.Monday:
        fmt.Println("Today is Monday.")
    case today == time.Tuesday:
        fmt.Println("Today is Tuesday.")
    case today == time.Wednesday:
        fmt.Println("Today is Wednesday.")
    case today == time.Thursday:
        fmt.Println("Today is Thursday.")
    case today == time.Friday:
        fmt.Println("Today is Friday.")
    case today == time.Saturday:
        fmt.Println("Today is Saturday.")
    default:
        fmt.Println("Today is Sunday.")
    }
}
go run switch.go

Результат выполнения (зависит от текущего дня):

Today is Monday.

В этой программе мы убрали переменную из строки со switch. При выполнении Go проверяет истинность условий в каждом блоке case. Как только условие становится истинным (true), выполняется код этой ветки, и работа блока switch завершается.

Оператор fallthrough

Как уже упоминалось, по умолчанию после выполнения подходящей ветки case программа выходит из switch.

Если вы хотите, чтобы после выполнения текущего блока программа перешла к выполнению следующего блока case без проверки его условия, используйте ключевое слово fallthrough.

Особенности использования fallthrough:

  • По умолчанию, если switch находит совпадение (например, case 10), он выполняет его и останавливается. fallthrough заставляет программу «провалиться» в следующую ветку.
  • fallthrough влияет только на следующий за ним case и не проверяет его условие.
  • fallthrough нельзя использовать в самой последней ветке switch.

Рассмотрим конкретный пример:

package main

import (
    "fmt"
)

func main() {
    n := 10
    switch n {
    case 10:
        fmt.Println(10)
        fallthrough
    case 3:
        fmt.Println(3)
    }
}
go run switch.go

Результат выполнения:

10
3

Несмотря на то, что n равно 10, а не 3, программа вывела оба числа, так как оператор fallthrough принудительно передал управление в следующий блок.

Инициализация внутри switch

В языке Go не только оператор if поддерживает блок инициализации — он доступен и в switch. Вы можете объявить переменную прямо перед условием, разделив их точкой с запятой.

Задание

Теперь вам нужно переписать программу из предыдущего раздела, перенеся инициализацию переменной внутрь оператора switch.

Создайте новый файл switch2.go. Напишите в нем код, который модифицирует пример с fallthrough, используя краткую инициализацию.

cd ~/project
touch switch2.go

Исходный код для модификации:

package main

import (
    "fmt"
)

func main() {
    n := 10
    switch n {
    case 10:
        fmt.Println(1)
        fallthrough
    case 3:
        fmt.Println(3)
    }
}

Требования:

  • Файл switch2.go должен находиться в директории ~/project.

Подсказка: Вы можете ориентироваться на то, как мы делали инициализацию в лабораторной работе по if-else.

Резюме

В этой лабораторной работе мы изучили оператор ветвления switch. Основные выводы:

  • Когда условие в case совпадает, выполняется соответствующий код, и программа выходит из блока switch.
  • Используйте fallthrough, если нужно продолжить выполнение следующего блока case без проверки условия.
  • В switch можно использовать блок инициализации, отделяя его от основного выражения точкой с запятой.
✨ Проверить решение и практиковаться