Переключатель типов сравнивает типы, а не значения. В остальном он аналогичен переключателю выражений. Он помечается специальным выражением-переключателем, которое имеет форму утверждения типа, используя зарезервированное слово 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 в неявном блоке каждого пункта. В пунктах со случаем точно одного типа переменная имеет этот тип; в противном случае переменная имеет тип выражения в 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" утверждение запрещено в переключателе типов.
Читайте также:
Комментариев нет:
Отправить комментарий