14. Что такое утверждение типа в языке Go?

Go

Привет всем, меня зовут Мин.

В период самостоятельного изучения Golang я написал подробные учебные заметки и разместил их в своем личном общедоступном аккаунте WeChat «Время программирования на Go».Что касается языка Go, я тоже новичок, поэтому то, что я написал, должно больше подходить для новых студентов, если вы только изучаете язык Go, вам стоит обратить на него внимание, учиться и расти вместе.

Мой онлайн-блог:golang.iswbm.comМой Github: github.com/iswbm/GolangCodingTime


Type Assertion

Утверждение типа (китайское название: утверждение типа), с помощью которого можно выполнять следующие действия.

  1. экзаменiравен нулю
  2. экзаменiЯвляется ли сохраненное значение определенного типа

Есть два конкретных способа его использования:

Первое:

t := i.(T)

Это выражение может утверждать, что объект интерфейса (i) не равен nil, а тип значения, хранящегося в объекте интерфейса (i), равен T. Если утверждение выполнено успешно, оно вернет значение t, а если утверждение не выполнено , это вызовет панику.

Давайте напишем кусок кода для тестирования

package main

import "fmt"

func main() {
    var i interface{} = 10
    t1 := i.(int)
    fmt.Println(t1)

    fmt.Println("=====分隔线=====")

    t2 := i.(string)
    fmt.Println(t2)
}

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

10
=====分隔线=====
panic: interface conversion: interface {} is int, not string

goroutine 1 [running]:
main.main()
        E:/GoPlayer/src/main.go:12 +0x10e
exit status 2

Если значение интерфейса, которое должно быть установлено, равно нулю, давайте посмотрим, вызовет ли оно панику, как ожидалось.

package main

func main() {
    var i interface{} // nil
    var _ = i.(interface{})
}

Вывод следующий, это действительно вызовет панику

panic: interface conversion: interface is nil, not interface {}

goroutine 1 [running]:
main.main()
        E:/GoPlayer/src/main.go:5 +0x34
exit status 2

секунда

t, ok:= i.(T)

Как и выше, это выражение также может утверждать, что объект интерфейса (i) не равен nil, а тип значения, хранящегося в объекте интерфейса (i), равен T. Если утверждение выполнено успешно, оно вернет свой тип t, и в настоящее время все в порядке. Значение true указывает, что утверждение было успешным.

Если тип значения интерфейса не соответствует утвержденному нами T, утверждение завершится ошибкой, но, в отличие от первого выражения, это не вызовет паники, а установит значение ok в false, указывая на то, что утверждение не выполнено. В этот момент t является нулевым значением Т.

Слегка измените приведенный выше пример следующим образом.

package main

import "fmt"

func main() {
    var i interface{} = 10
    t1, ok := i.(int)
    fmt.Printf("%d-%t\n", t1, ok)

    fmt.Println("=====分隔线1=====")

    t2, ok := i.(string)
    fmt.Printf("%s-%t\n", t2, ok)

    fmt.Println("=====分隔线2=====")

    var k interface{} // nil
    t3, ok := k.(interface{})
    fmt.Println(t3, "-", ok)

    fmt.Println("=====分隔线3=====")
    k = 10
    t4, ok := k.(interface{})
    fmt.Printf("%d-%t\n", t4, ok)

    t5, ok := k.(int)
    fmt.Printf("%d-%t\n", t5, ok)
}

Вывод после запуска следующий: можно обнаружить, что когда выполняется второе утверждение, хотя оно и не выполняется, паника не срабатывает.

10-true
=====分隔线1=====
-false
=====分隔线2=====
<nil> - false
=====分隔线3=====
10-true
10-true

В приведенном выше выводе вы должны заметить, что вывод второго утверждения находится в-falseДело не в том, что раньше не было значения вывода t2, а в том, что утверждение не выполняется, поэтому t2 также получает нулевое значение строки."", который имеет нулевую длину, поэтому вы не можете видеть его вывод.

Type Switch

Если вам нужно различать несколько типов, вы можете использовать утверждения переключения типов, которые будут проще, более прямыми и более эффективными, чем утверждения типа по одному.

package main

import "fmt"

func findType(i interface{}) {
    switch x := i.(type) {
    case int:
        fmt.Println(x, "is int")
    case string:
        fmt.Println(x, "is string")
    case nil:
        fmt.Println(x, "is nil")
    default:
        fmt.Println(x, "not type matched")
    }
}

func main() {
    findType(10)      // int
    findType("hello") // string

    var k interface{} // nil
    findType(k)

    findType(10.23) //float64
}

Вывод выглядит следующим образом

10 is int
hello is string
<nil> is nil
10.23 not type matched

Дополнительное примечание:

  • Если ваше значение равно нулю, то совпадениеcase nil
  • Если ваше значение не соответствует соответствующему типу в switch-case, то возьмите ветку по умолчанию

Справочная статья

Руководство по серии

01. Построение среды разработки (Goland & VS Code)

02. Изучите пять методов создания переменных

03. Подробные типы данных:**Целое число и число с плавающей запятой**

04. Подробные типы данных: байт, руна и строка

05. Подробно объясните типы данных: массивы и срезы

06. Подробно объясните типы данных: словари и логические значения

07. Подробно объясните типы данных: указатели

08. Объектно-ориентированное программирование: структуры и наследование

09. Статья для понимания функций в Go

10. Управление потоком языка Go: условный оператор if-else

11. Управление потоком языка Go: оператор выбора switch-case

12. Управление потоком языка Go: оператор цикла for

13. Перейти к управлению языковым потоком: перейти к безусловному переходу

14. Перейти к управлению языковым потоком: отложить отложенный вызов

15. Объектно-ориентированное программирование: интерфейсы и полиморфизм

16. Ключевые слова: В чем разница между make и new?

17. Статья о понимании блоков и области видимости в Go

18. Изучите Go Coroutines: горутины

19. Изучите сопрограммы Go: подробно объясните каналы/каналы

20. Подробное объяснение нескольких классических случаев ошибки взаимоблокировки канала.

21. Изучите сопрограммы Go: группа ожидания

22. Изучите процедуры Go: мьютексы и блокировки чтения-записи

23. Обработка исключений в Go: паника и восстановление

24. Сверхдетальная интерпретация прошлой жизни Go Modules и вводное использование

25. 8 важных знаний об импорте пакетов на языке Go

26. Как открыть исходный код модулей, которые я написал для использования другими?

27. Расскажите об утверждениях типов в Go?

28. Эти пять пунктов помогут вам понять, как использовать select в языке Go.