Запятая-ok при assertion
Конструкция запятая-ok (comma-ok idiom) при assertion
(утверждении типа) позволяет безопасно проверить,
хранит ли интерфейс значение конкретного типа.
В отличие от обычного утверждения типа, которое вызывает панику
при несовпадении, эта конструкция возвращает два значения:
извлеченное значение и булево значение, указывающее на успех операции.
Синтаксис
value, ok := interfaceVar.(TargetType)
Где interfaceVar — переменная типа интерфейса,
TargetType — тип, на который мы пытаемся утвердить,
value — значение целевого типа (если утверждение успешно),
ok — булево значение, которое равно true,
если интерфейс содержит значение типа TargetType,
и false в противном случае.
Пример
Давайте проверим, содержит ли интерфейс значение типа int:
package main
import "fmt"
func main() {
var i interface{} = 42
value, ok := i.(int)
if ok {
fmt.Println("Value is int:", value)
} else {
fmt.Println("Value is not int")
}
}
Результат выполнения кода:
"Value is int: 42"
Пример
Давайте проверим, содержит ли интерфейс значение типа string,
когда на самом деле там хранится int:
package main
import "fmt"
func main() {
var i interface{} = 12345
value, ok := i.(string)
if ok {
fmt.Println("Value is string:", value)
} else {
fmt.Println("Value is not string")
}
}
Результат выполнения кода:
"Value is not string"
Обратите внимание, что в этом случае паники не произошло,
а переменная value содержит нулевое значение для типа
string (пустую строку), так как утверждение не удалось.
Пример
Часто конструкцию с запятой-ok используют в сочетании с
switch для проверки нескольких возможных типов:
package main
import "fmt"
func main() {
var i interface{} = []int{1, 2, 3, 4, 5}
switch v := i.(type) {
case int:
fmt.Println("int:", v)
case string:
fmt.Println("string:", v)
case []int:
fmt.Println("slice of ints:", v)
default:
fmt.Println("unknown type")
}
}
Результат выполнения кода:
"slice of ints: [1 2 3 4 5]"
Смотрите также
-
конструкцию
type-assertion,
которая выполняет утверждение типа без проверки -
конструкцию
type-switch,
которая позволяет выполнять действия в зависимости от типа -
понятие
пустого интерфейса,
который может хранить значение любого типа -
тип
any,
который является псевдонимом для пустого интерфейса в Go 1.18+