Уроки модуля (3/5)
Тип переключателя
Переключатель типа различает несколько возможных типов объекта.
значение интерфейса. Это обобщение 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 сам использует переключатель типа для обработки
стандартные форматы.
Переключение типа против отражения
Для нескольких известных типов → переключатель типа (быстрый, читаемый).
Для динамической проверки неизвестных типов → пакет reflect (подробнее
мощный, но медленнее и многословнее).
Попробуйте это
Реализуйте строку описания(i интерфейс{}), которая возвращает «int», «string» или «altro» в зависимости от динамического типа.
Показать подсказку
Синтаксис: `switch i.(type) {case T: ... default: ... }`.
Решение доступно после 3 попыток
Напишите printVal(i интерфейс{}), который использует v := i.(type) и печатает с %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+ типа → переключатель типа.