14. Go 語言中的類型斷言是什麼?

Hi,你們好,我是明哥。git

在本身學習 Golang 的這段時間裏,我寫了詳細的學習筆記放在個人我的微信公衆號 《Go編程時光》,對於 Go 語言,我也算是個初學者,所以寫的東西應該會比較適合剛接觸的同窗,若是你也是剛學習 Go 語言,不防關注一下,一塊兒學習,一塊兒成長。github

個人在線博客:golang.iswbm.com 個人 Github:github.com/iswbm/GolangCodingTimegolang


Type Assertion

Type Assertion(中文名叫:類型斷言),經過它能夠作到如下幾件事情 編程

  1. 檢查 i 是否爲 nil
  2. 檢查 i 存儲的值是否爲某個類型

具體的使用方式有兩種:數組

第一種:微信

t := i.(T)複製代碼

這個表達式能夠斷言一個接口對象(i)裏不是 nil,而且接口對象(i)存儲的值的類型是 T,若是斷言成功,就會返回值給 t,若是斷言失敗,就會觸發 panic。函數

來寫段代碼試驗一下學習

package main

import "fmt"

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

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

    t2 := i.(string)
    fmt.Println(t2)
}複製代碼

運行後輸出以下,能夠發如今執行第二次斷言的時候失敗了,而且觸發了 panicspa

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

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

若是要斷言的接口值是 nil,那咱們來看看也是否是也如預期同樣會觸發panic3d

package main

func main() {
    var i interface{} // nil
    var _ = i.(interface{})
}複製代碼

輸出以下,確實是會 觸發 panic

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,而且此時 ok 的值 爲 true,表示斷言成功。

若是接口值的類型,並非咱們所斷言的 T,就會斷言失敗,但和第一種表達式不一樣的事,這個不會觸發 panic,而是將 ok 的值設爲 false ,表示斷言失敗,此時t 爲 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)
}複製代碼

運行後輸出以下,能夠發如今執行第二次斷言的時候,雖然失敗了,但並無觸發了 panic。

10-true
=====分隔線1=====
-false
=====分隔線2=====
<nil> - false
=====分隔線3=====
10-true
10-true複製代碼

上面這段輸出,你要注意的是第二個斷言的輸出在-false 以前並非有沒有輸出任何 t2 的值,而是因爲斷言失敗,因此 t2 獲得的是 string 的零值也是 "" ,它是零長度的,因此你看不到其輸出。

Type Switch

若是須要區分多種類型,能夠使用 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複製代碼

額外說明一下:

  • 若是你的值是 nil,那麼匹配的是 case nil
  • 若是你的值在 switch-case 裏並無匹配對應的類型,那麼走的是 default 分支

參考文章

系列導讀

01. 開發環境的搭建(Goland & VS Code)

02. 學習五種變量建立的方法

03. 詳解數據類型:**整形與浮點型**

04. 詳解數據類型:byte、rune與string

05. 詳解數據類型:數組與切片

06. 詳解數據類型:字典與布爾類型

07. 詳解數據類型:指針

08. 面向對象編程:結構體與繼承

09. 一篇文章理解 Go 裏的函數

10. Go語言流程控制:if-else 條件語句

11. Go語言流程控制:switch-case 選擇語句

12. Go語言流程控制:for 循環語句

13. Go語言流程控制:goto 無條件跳轉

14. Go語言流程控制:defer 延遲調用

15. 面向對象編程:接口與多態

16. 關鍵字:make 和 new 的區別?

17. 一篇文章理解 Go 裏的語句塊與做用域

18. 學習 Go 協程:goroutine

19. 學習 Go 協程:詳解信道/通道

20. 幾個信道死鎖經典錯誤案例詳解

21. 學習 Go 協程:WaitGroup

22. 學習 Go 協程:互斥鎖和讀寫鎖

23. Go 裏的異常處理:panic 和 recover

24. 超詳細解讀 Go Modules 前世此生及入門使用

25. Go 語言中關於包導入必學的 8 個知識點

26. 如何開源本身寫的模塊給別人用?

27. 說說 Go 語言中的類型斷言?

28. 這五點帶你理解Go語言的select用法


相關文章
相關標籤/搜索