Golang详解类型断言

Type Assertion

Type Assertion(中文名叫:类型断言),通过它可以做到以下几件事情

  1. 检查 i 是否为 nil
  2. 检查 i 存储的值是否为某个类型

具体的使用方式有两种:

第一种:

t := i.(T)

这个表达式可以断言一个接口对象(i)里不是 nil,并且接口对象(i)存储的值的类型是 T,如果断言成功,就会返回值给 t,如果断言失败,就会触发 panic。

来写段代码试验一下

var i interface{} = 10
	t1 := i.(int64)
	fmt.Println(t1)
	fmt.Println("=====分隔线=====")
	t2 := i.(string)
	fmt.Println(t2)

运行后输出如下,可以发现在执行第二次断言的时候失败了,并且触发了 panic

如果要断言的接口值是 nil,那我们来看看也是不是也如预期一样会触发panic

	var i3 interface{}
	t3 := i3.(interface{})
	fmt.Println(t3)

输出如下,确实是会 触发 panic

第二种

t, ok:= i.(T)

和上面一样,这个表达式也是可以断言一个接口对象(i)里不是 nil,并且接口对象(i)存储的值的类型是 T,如果断言成功,就会返回其值给 t,并且此时 ok 的值 为 true,表示断言成功。

如果接口值的类型,并不是我们所断言的 T,就会断言失败,但和第一种表达式不同的事,这个不会触发 panic,而是将 ok 的值设为 false表示断言失败,此时t 为 T 的零值

稍微修改下上面的例子,如下

	var i4 interface{} = 10
	t1, ok := i4.(int)
	fmt.Printf("%d-%t\n", t1, ok)
	fmt.Println("=====分隔线1=====")
	t2, ok := i4.(string)
	fmt.Printf("%s-%t\n", t2, ok)
	fmt.Println("=====分隔线2=====")
	var k interface{}
	t3, ok := k.(interface{})
	fmt.Println(t3, "-", ok)
	fmt.Println("=====分隔线3=====")
	k = 10
	t4, ok := k.(interface{})
	fmt.Printf("%d-%t\n", t4, ok)
	fmt.Println("=====分隔线4=====")
	var s interface{} = "stars"
	t5, ok := s.(string)
	fmt.Printf("%s-%t\n", t5, ok)
	fmt.Println("=====分隔线5=====")
	t6, ok := k.(int)
	fmt.Printf("%d-%t\n", t6, ok)

 

运行后输出如下,可以发现在执行第二第三次断言的时候,虽然失败了,但并没有触发了 panic。

上面这段输出,你要注意的是第二个断言的输出在-false 之前并不是有没有输出任何 t2 的值,而是由于断言失败,所以 t2 得到的是 string 的零值也是 "" ,它是零长度的,所以你看不到其输出。

Type Switch

如果需要区分多种类型,可以使用 type switch 断言,这个将会比一个一个进行类型断言更简单、直接、高效。

func findType(i interface{}) {
	switch x := i.(type) {
	case int:
		fmt.Println(x, "is int")
	case string:
		fmt.Println(x, "is string")
	case rune:
		fmt.Println(x, "is rune")
	case nil:
		fmt.Println(x, "is nil")
	default:
		fmt.Println(x, "not type matched")
	}
}
func Demo2Process() {
	findType(10)
	findType("linrux")
	var k interface{}
	findType(k)
	findType(10.89)
}

输出如下:

额外说明一下:

  • 如果你的值是 nil,那么匹配的是 case nil
  • 如果你的值在 switch-case 里并没有匹配对应的类型,那么走的是 default 分支

此外,还有两点需要你格外注意

  1. 类型断言,仅能对静态类型为空接口(interface{})的对象进行断言,否则会抛出错误
  2. 类型断言完成后,实际上会返回静态类型为你断言的类型的对象,而要清楚原来的静态类型为空接口类型(interface{}),这是 Go 的隐式转换。

版权声明:
作者:linrux
链接:https://www.tot7.cn/technology/go/549.html
来源:阿信博客
文章版权归作者所有,未经允许请勿转载。

THE END
分享
二维码
< <上一篇
下一篇>>
文章目录
关闭
目 录