go语言类型断言怎么使用
本篇内容主要讲解“go语言类型断言怎么使用”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“go语言类型断言怎么使用”吧!
在go语言中,类型断言是一个使用在接口值上的操作,用于检查接口类型变量所持有的值是否实现了期望的接口或者具体的类型,语法为“value, ok := x.(T)”。通过类型断言可以做到的事情:1、检查i是否为nil;2、检查i存储的值是否为某个类型。
断言是什么?
断言是编程术语,表示为一些布尔表达。编写代码时,我们总是会做出一些假设,断言就是用于在代码中捕捉这些假设。简单的来理解断言的话就是判断的意思。所以在Go中类型断言我们就可以理解成对类型的判断。
类型断言介绍
类型断言(Type Assertion)是一个使用在接口值上的操作,用于检查接口类型变量所持有的值是否实现了期望的接口或者具体的类型。
在Go语言中类型断言的语法格式如下:
value, ok := x.(T)
其中,x 表示一个接口的类型,T 表示一个具体的类型(也可为接口类型)。
该断言表达式会返回 x 的值(也就是 value)和一个布尔值(也就是 ok),可根据该布尔值判断 x 是否为 T 类型:
如果 T 是具体某个类型,类型断言会检查 x 的动态类型是否等于具体类型 T。如果检查成功,类型断言返回的结果是 x 的动态值,其类型是 T。
如果 T 是接口类型,类型断言会检查 x 的动态类型是否满足 T。如果检查成功,x 的动态值不会被提取,返回值是一个类型为 T 的接口值。
无论 T 是什么类型,如果 x 是 nil 接口值,类型断言都会失败。
在Go中类型断言主要有两种形式
变量.(类型)
。例如:i.(int)变量,bool = 变量.(类型)
。例如:num,ok = i.(int)。ok表示判断类型是否成功的意思。
类型断言的用法
通过类型断言可以做到以下几件事情
检查
i
是否为 nil检查
i
存储的值是否为某个类型
具体的使用方式有两种:
第一种:
t := i.(T)
这个表达式可以断言一个接口对象(i)里不是 nil,并且接口对象(i)存储的值的类型是 T,如果断言成功,就会返回值给 t,如果断言失败,就会触发 panic。
来写段代码试验一下
package mainimport "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 stringgoroutine 1 [running]:main.main() E:/GoPlayer/class="lazy" data-src/main.go:12 +0x10eexit status 2
如果要断言的接口值是 nil,那我们来看看也是不是也如预期一样会触发panic
package mainfunc main() { var i interface{} // nil var _ = i.(interface{})}
输出如下,确实是会 触发 panic
panic: interface conversion: interface is nil, not interface {}goroutine 1 [running]:main.main() E:/GoPlayer/class="lazy" data-src/main.go:5 +0x34exit status 2
第二种
t, ok:= i.(T)
和上面一样,这个表达式也是可以断言一个接口对象(i)里不是 nil,并且接口对象(i)存储的值的类型是 T,如果断言成功,就会返回其类型给 t,并且此时 ok 的值 为 true,表示断言成功。
如果接口值的类型,并不是我们所断言的 T,就会断言失败,但和第一种表达式不同的事,这个不会触发 panic,而是将 ok 的值设为 false ,表示断言失败,此时t 为 T 的零值。
稍微修改下上面的例子,如下
package mainimport "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-true10-true
上面这段输出,你要注意的是第二个断言的输出在-false
之前并不是有没有输出任何 t2 的值,而是由于断言失败,所以 t2 得到的是 string 的零值也是 ""
,它是零长度的,所以你看不到其输出。
Type Switch
如果需要区分多种类型,可以使用 type switch 断言,这个将会比一个一个进行类型断言更简单、直接、高效。
package mainimport "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 inthello is string<nil> is nil10.23 not type matched
额外说明一下:
如果你的值是 nil,那么匹配的是
case nil
如果你的值在 switch-case 里并没有匹配对应的类型,那么走的是 default 分支
到此,相信大家对“go语言类型断言怎么使用”有了更深的了解,不妨来实际操作一番吧!这里是编程网网站,更多相关内容可以进入相关频道进行查询,关注我们,继续学习!
免责声明:
① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。
② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341