Hi,大家好,我是明哥,
在自己學習 Golang 的這段時間里,我寫了詳細的學習筆記放在我的個人微信公眾號 《Go編程時光》,對于 Go 語言,我也算是個初學者,因此寫的東西應該會比較適合剛接觸的同學,如果你也是剛學習 Go 語言,不防關注一下,一起學習,一起成長,
我的在線博客:http://golang.iswbm.com
我的 Github:github.com/iswbm/GolangCodingTime
Type Assertion
Type Assertion(中文名叫:型別斷言),通過它可以做到以下幾件事情
- 檢查
i是否為 nil - 檢查
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)
}
運行后輸出如下,可以發現在執行第二次斷言的時候失敗了,并且觸發了 panic
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,那我們來看看也是不是也如預期一樣會觸發panic
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 分支
參考文章
- Explain Type Assertions in Go
- Go interface 詳解 (四) :型別斷言
系列導讀
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用法

轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/13854.html
標籤:Go
上一篇:Kubernetes 基礎資料
下一篇:GO學習Day1
