Type switch — это специальная конструкция в Go, позволяющая определять и обрабатывать разные типы данных в интерфейсной переменной.
switch v := i.(type) {
case T1:
// здесь v имеет тип T1
case T2:
// здесь v имеет тип T2
default:
// случай, когда тип не соответствует ни одному из case
}
i.(type)
(только внутри type switch)i
v
имеет конкретный тип из casefunc printType(i interface{}) {
switch v := i.(type) {
case int:
fmt.Printf("Integer: %d\n", v)
case string:
fmt.Printf("String: %s\n", v)
case bool:
fmt.Printf("Boolean: %v\n", v)
default:
fmt.Printf("Unknown type: %T\n", v)
}
}
.(type)
вместо значенияЧаще всего применяется с interface{}
для обработки разных типов:
func process(value interface{}) {
switch v := value.(type) {
case []byte:
// обработка []byte
case string:
// обработка string
}
}
Отлично работает с пользовательскими структурами:
type Dog struct { Name string }
type Cat struct { Name string }
func greet(pet interface{}) {
switch v := pet.(type) {
case Dog:
fmt.Printf("Woof! I'm %s\n", v.Name)
case Cat:
fmt.Printf("Meow! I'm %s\n", v.Name)
}
}
Можно обнаружить nil-значение:
switch v := i.(type) {
case nil:
fmt.Println("nil value")
default:
fmt.Printf("Type: %T\n", v)
}
Type switch — это расширенная версия type assertion:
// Type assertion
if s, ok := i.(string); ok {
fmt.Println(s)
}
// Эквивалентный type switch
switch s := i.(type) {
case string:
fmt.Println(s)
}
Type switch обычно быстрее серии if-else с type assertions, так как компилятор оптимизирует его как таблицу переходов.
v
в каждом case имеет разную область видимостиМожно использовать для реализации visitor-паттерна:
func visit(node interface{}) {
switch n := node.(type) {
case *AstNode:
visitChildren(n.Children)
case *LiteralNode:
processLiteral(n.Value)
}
}