# переключатель типов (type switch)

**Переключатель типов** сравнивает типы, а не значения. В остальном он аналогичен переключателю выражений. Он помечается специальным выражением-переключателем, которое имеет форму утверждения типа, используя зарезервированное слово type, а не фактический тип:

```
switch x.(type) {
// cases
}
```

Затем случаи (cases) сопоставляют фактические типы T с динамическим типом выражения x. Как и в утверждении типа, x должен иметь интерфейсный тип, и каждый неинтерфейсный тип T, указанный в случае (case), должен реализовывать тип x. Типы, перечисленные в случаях переключения типов, должны быть разными.

```
TypeSwitchStmt  = "switch" [ SimpleStmt ";" ] TypeSwitchGuard "{" { TypeCaseClause } "}" .
TypeSwitchGuard = [ identifier ":=" ] PrimaryExpr "." "(" "type" ")" .
TypeCaseClause  = TypeSwitchCase ":" StatementList .
TypeSwitchCase  = "case" TypeList | "default" .
TypeList        = Type { "," Type } .
```

TypeSwitchGuard может включать краткое объявление переменной. Когда эта форма используется, переменная объявляется в конце TypeSwitchCase в [неявном блоке](https://golang-blog.blogspot.com/2019/05/go-specification-blocks.html) каждого пункта. В пунктах со случаем точно одного типа переменная имеет этот тип; в противном случае переменная имеет тип выражения в TypeSwitchGuard.

Вместо типа случай (case) может использовать предварительно объявленный идентификатор nil; этот случай выбирается, когда выражение в TypeSwitchGuard имеет нулевое значение интерфейса. Может быть не более одного нулевого случая.

Дано выражение x типа interface{}, следующий переключатель типов:

```
switch i := x.(type) {
case nil:
    printString("x is nil")                // тип i это тип x (interface{})
case int:
    printInt(i)                            // тип i это int
case float64:
    printFloat64(i)                        // тип i это float64
case func(int) float64:
    printFunction(i)                       // тип i это func(int) float64
case bool, string:
    printString("type is bool or string")  // тип i это тип x (interface{})
default:
    printString("don't know the type")     // тип i это тип x (interface{})
}
```

может быть записан как:

```
v := x  // x оценивается только единожды
if v == nil {
    i := v                                 // тип i это тип x (interface{})
    printString("x is nil")
} else if i, isInt := v.(int); isInt {
    printInt(i)                            // тип i это int
} else if i, isFloat64 := v.(float64); isFloat64 {
    printFloat64(i)                        // тип i это float64
} else if i, isFunc := v.(func(int) float64); isFunc {
    printFunction(i)                       // тип i это func(int) float64
} else {
    _, isBool := v.(bool)
    _, isString := v.(string)
    if isBool || isString {
        i := v                         // тип i это тип x (interface{})
        printString("type is bool or string")
    } else {
        i := v                         // тип i это тип x (interface{})
        printString("don't know the type")
    }
}
```

Защите переключения типа может предшествовать простое утверждение, которое выполняется до оценки защиты.

"fallthrough" утверждение запрещено в переключателе типов.


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://folko.gitbook.io/goland/specifikaciya-1/pereklyuchatel-tipov-type-switch.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
