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

2021-10-06 03:16:09 字數 4146 閱讀 5126

type assertion(中文名叫:型別斷言),通過它可以做到以下幾件事情

檢查i是否為 nil

檢查i儲存的值是否為某個型別

具體的使用方式有兩種:

第一種:

t := i.(t)
這個表示式可以斷言乙個介面物件(i)裡不是 nil,並且介面物件(i)儲存的值的型別是 t,如果斷言成功,就會返回值給 t,如果斷言失敗,就會觸發 panic。

來寫段**試驗一下

package main

import "fmt"

func main() = 10

t1 := i.(int)

fmt.println(t1)

fmt.println("*****分隔線*****")

t2 := i.(string)

fmt.println(t2)

}

執行後輸出如下,可以發現在執行第二次斷言的時候失敗了,並且觸發了 panic

10

*****分隔線*****

panic: inte***ce conversion: inte***ce {} is int, not string

goroutine 1 [running]:

main.main()

e:/goplayer/src/main.go:12 +0x10e

exit status 2

如果要斷言的介面值是 nil,那我們來看看也是不是也如預期一樣會觸發panic

package main

func main() // nil

var _ = i.(inte***ce{})

}

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

panic: inte***ce conversion: inte***ce is nil, not inte***ce {}

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() = 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 inte***ce{} // nil

t3, ok := k.(inte***ce{})

fmt.println(t3, "-", ok)

fmt.println("*****分隔線3*****")

k = 10

t4, ok := k.(inte***ce{})

fmt.printf("%d-%t\n", t4, ok)

t5, ok := k.(int)

fmt.printf("%d-%t\n", t5, ok)

}

執行後輸出如下,可以發現在執行第二次斷言的時候,雖然失敗了,但並沒有觸發了 panic。

10-true

*****分隔線1*****

-false

*****分隔線2*****

- false

*****分隔線3*****

10-true

10-true

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

如果需要區分多種型別,可以使用 type switch 斷言,這個將會比乙個乙個進行型別斷言更簡單、直接、高效。

package main

import "fmt"

func findtype(i inte***ce{})

}func main() // nil

findtype(k)

findtype(10.23) //float64

}

輸出如下

10 is int

hello is string

is nil

10.23 not type matched

額外說明一下:

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用法

go語言的型別斷言 Type Assertion

x.t 檢查x的動態型別是否是t,其中x必須是介面值。如果t是具體型別 型別斷言檢查x的動態型別是否等於具體型別t。如果檢查成功,型別斷言返回的結果是x的動態值,其型別是t。換句話說,對介面值x斷言其動態型別是具體型別t,若成功則提取出x的具體值。如果檢查失敗則panic。例如 var w io.w...

GO語言中的StructTag型別

structtag是什麼?在go語言裡,structtag是乙個標記字串,此字串可跟隨在struct中欄位定義的後面。structtag就是一系列的 key value 形式的組合,其中key是乙個不可為空的字串,key value組合可以有多個,空格分隔。structtag有什麼用?structt...

C語言中的EOF是什麼?

日期 2011年11月12日 我學習c語言的時候,遇到的乙個問題就是eof。它是end of file的縮寫,表示 文字流 stream 的結尾。這裡的 文字流 可以是檔案 file 也可以是標準輸入 stdin 比如,下面這段 就表示,如果不是檔案結尾,就把檔案的內容複製到螢幕上。int c wh...