Модульні уроки (3/5)
Перемикач типу
Перемикач типу розрізняє кілька можливих типів an
значення інтерфейсу. Це узагальнення comma ok, якщо вони є
більше одного випадку.
Синтаксис
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 intvмає типint.defaultловить усі інші типи; тамvмає тип оригінального інтерфейсу.case nilвідповідає інтерфейсу з нульовим динамічним типом.
«Безіменна» справа
Якщо вам не потрібне введене значення, ви можете опустити v:
switch i.(type) {
case int:
// you know it's an int, but you don't have a variable of that type
case string:
// ...
}Форма, яка використовується, коли вам потрібно просто розрізнити тип, а не оперувати на значення.
Кілька типів в одному регістрі
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)
}Типовий випадок використання: форматований друк
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 (докладніше
потужний, але повільніший і багатослівніший).
Спробуйте
Реалізуйте рядок describe(i interface{}), який повертає «int», «string» або «altro» залежно від динамічного типу.
Показати підказку
Синтаксис: `switch i.(type) { case T: ... default: ... }`.
Рішення доступне після 3 спроб
Напишіть інтерфейс printVal(i{}), який використовує v := i.(тип) і друкує з %d для int, %s для рядка.
Показати підказку
Всередині `case int` v має тип int (ви можете передати його Printf).
Рішення доступне після 3 спроб
З якого синтаксису починається зміна типу?
switch ??? {
case int: ...
}Підведення підсумків
switch v := i.(type) { case T: ... }: розрізняє динамічний тип.- Усередині корпусу одного типу
vмає тип корпусу. case T1, T2:vзберігає вихідний тип інтерфейсу.defaultдля необроблених випадків;case nilдля нульового інтерфейсу.- Немає
fallthroughв перемикачах типу. - 1 тип → тип твердження; 2+ типу → перемикач типу.