Перейти до основного вмісту
Модуль 6 · Урок 3 із 528/50 у курсі~10 min
Модульні уроки (3/5)

Перемикач типу

Перемикач типу розрізняє кілька можливих типів an значення інтерфейсу. Це узагальнення comma ok, якщо вони є більше одного випадку.

Синтаксис

Go
func describe(i interface{}) string {
    switch v := i.(type) {
    case int:
        return fmt.Sprintf("int %d", v)
    case string:
        return fmt.Sprintf("string %q", v)
    case nil:
        return "nil"
    default:
        return fmt.Sprintf("altro tipo: %T", v)
    }
}
  • i.(type) — це спеціальний синтаксис, дійсний ТІЛЬКИ всередині switch.
  • v := ... пов’язує значення з поточним типом випадку: всередині case int v має тип int.
  • default ловить усі інші типи; там v має тип оригінального інтерфейсу.
  • case nil відповідає інтерфейсу з нульовим динамічним типом.

«Безіменна» справа

Якщо вам не потрібне введене значення, ви можете опустити v:

Go
switch i.(type) {
case int:
    // you know it's an int, but you don't have a variable of that type
case string:
    // ...
}

Форма, яка використовується, коли вам потрібно просто розрізнити тип, а не оперувати на значення.

Кілька типів в одному регістрі

Go
switch v := i.(type) {
case int, int64:
    // here v is still interface{}: the "common" type is just the interface
    fmt.Println("numero intero:", v)
case string:
    // here v is string
    fmt.Println("stringa:", v)
}

Типовий випадок використання: форматований друк

Go
func print(i interface{}) {
    switch v := i.(type) {
    case int:
        fmt.Printf("%d\n", v)
    case string:
        fmt.Printf("%s\n", v)
    case fmt.Stringer:
        fmt.Println(v.String())
    default:
        fmt.Printf("%v\n", v)
    }
}

Сам fmt.Println використовує внутрішній перемикач типу для обробки стандартні формати.

Перемикач типу проти відображення

Для кількох відомих типів → тип switch (швидкий, читабельний). Для динамічної перевірки невідомих типів → пакет reflect (докладніше потужний, але повільніший і багатослівніший).

Спробуйте

вправи#go.m6.l3.e1
Спроби: 0Завантаження…

Реалізуйте рядок describe(i interface{}), який повертає «int», «string» або «altro» залежно від динамічного типу.

Завантаження редактора…
Показати підказку

Синтаксис: `switch i.(type) { case T: ... default: ... }`.

Рішення доступне після 3 спроб

вправи#go.m6.l3.e2
Спроби: 0Завантаження…

Напишіть інтерфейс printVal(i{}), який використовує v := i.(тип) і друкує з %d для int, %s для рядка.

Завантаження редактора…
Показати підказку

Всередині `case int` v має тип int (ви можете передати його Printf).

Рішення доступне після 3 спроб

Quiz#go.m6.l3.e3
Готовий

З якого синтаксису починається зміна типу?

Go
switch ??? {
  case int: ...
}
Варіанти відповідей

Підведення підсумків

  • switch v := i.(type) { case T: ... }: розрізняє динамічний тип.
  • Усередині корпусу одного типу v має тип корпусу.
  • case T1, T2: v зберігає вихідний тип інтерфейсу.
  • default для необроблених випадків; case nil для нульового інтерфейсу.
  • Немає fallthrough в перемикачах типу.
  • 1 тип → тип твердження; 2+ типу → перемикач типу.