从零学习 Go 语言(14):Go 语言中的类型断言是什么?

hello_wbm · · 712 次点击 · · 开始浏览    
这是一个创建于 的文章,其中的信息可能已经有所发展或是发生改变。

![](http://image.iswbm.com/20200607145423.png) 在线博客:http://golang.iswbm.com/ Github:https://github.com/iswbm/GolangCodingTime --- ## Type Assertion Type Assertion(中文名叫:类型断言),通过它可以做到以下几件事情 1. 检查 `i` 是否为 nil 2. 检查 `i` 存储的值是否为某个类型 具体的使用方式有两种: **第一种:** ``` t := i.(T) ``` 这个表达式可以断言一个接口对象(i)里不是 nil,并且接口对象(i)存储的值的类型是 T,如果断言成功,就会返回值给 t,如果断言失败,就会触发 panic。 来写段代码试验一下 ```go 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 ```go 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 的零值。 稍微修改下上面的例子,如下 ```go 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 断言,这个将会比一个一个进行类型断言更简单、直接、高效。 ```go 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](https://stackoverflow.com/questions/38816843/explain-type-assertions-in-go) - [Go interface 详解 (四) :类型断言](https://sanyuesha.com/2017/12/01/go-interface-4/) **系列导读** [从零学习 Go 语言(01):一文搞定开发环境的搭建](https://studygolang.com/articles/27365) [从零学习 Go 语言(02):学习五种变量创建的方法](https://studygolang.com/articles/27432) [从零学习 Go 语言(03):数据类型之整型与浮点型](https://studygolang.com/articles/27440) [从零学习 Go 语言(04):byte、rune与字符串](https://studygolang.com/articles/27463) [从零学习 Go 语言(05):数据类型之数组与切片](https://studygolang.com/articles/27508) [从零学习 Go 语言(06):数据类型之字典与布尔类型](https://studygolang.com/articles/27563) [从零学习 Go 语言(07):数据类型之指针](https://studygolang.com/articles/27585) [从零学习 Go 语言(08):流程控制之if-else](https://studygolang.com/articles/27613) [从零学习 Go 语言(09):流程控制之switch-case](https://studygolang.com/articles/27660) [从零学习 Go 语言(10):流程控制之for 循环](https://studygolang.com/articles/28120) [从零学习 Go 语言(11):goto 无条件跳转](https://studygolang.com/articles/28472) [从零学习 Go 语言(12):流程控制之defer 延迟语句](https://studygolang.com/articles/28515) [从零学习 Go 语言(13):异常机制 panic 和 recover](https://studygolang.com/articles/28519) --- ![](http://image.python-online.cn/20200321153457.png)

有疑问加站长微信联系(非本文作者))

入群交流(和以上内容无关):加入Go大咖交流群,或添加微信:liuxiaoyan-s 备注:入群;或加QQ群:692541889

712 次点击  
加入收藏 微博
添加一条新回复 (您需要 登录 后才能回复 没有账号 ?)
  • 请尽量让自己的回复能够对别人有帮助
  • 支持 Markdown 格式, **粗体**、~~删除线~~、`单行代码`
  • 支持 @ 本站用户;支持表情(输入 : 提示),见 Emoji cheat sheet
  • 图片支持拖拽、截图粘贴等方式上传