类型断言 type assertion
和上节的类型转换不同,类型断言是将接口类型的值x,转换成类型T。
格式为:
x.(T)
v := x.(T)
v, ok := x.(T)
类型断言的必要条件是x是接口类型,非接口类型的x不能做类型断言:
var i int = 10
v := i.(int) //错误
T可以是非接口类型,如果想断言合法,则T应该实现x的接口。
T也可以是接口,则x的动态类型也应该实现接口T。
var x interface{} = 7 // x 的动态类型为int, 值为 7
i := x.(int) // i 的类型为 int, 值为 7
type I interface { m() }
var y I
s := y.(string) // 非法: string 没有实现接口 I (missing method m)
r := y.(io.Reader) // y如果实现了接口io.Reader和I的情况下, r的类型则为io.Reader
类型断言如果非法,运行时时候就会出现 impossible type assertion panic,为了避免这种情况,可以使用下面的语法:
v, ok = x.(T)
v, ok := x.(T)
var v, ok = x.(T)
ok代表类型断言是否合法,如果非法ok =false,v为T的零值,这样就不会出现运行时panic了。
希望你能记住,类型转换和类型断言完全是两个概念。
类型切换 type switch
类型切换(暂且这么翻译吧,英语更准确)用来比较类型而不是对值进行比较。
switch语句虽然在下一章中去讲,但是对于读者来说,多少会一种或者几种常用的编程语言,switch是一个条件语句,它可以判断某个值是否匹配某个case clause。但是对于type switch,它检查的是值x的类型T是否匹配某个类型。
格式如下,类型类型断言,但是括号内的不是某个具体的类型,而是单词type:
switch x.(type) {
// cases
}
type switch语句中可以有一个简写的变量声明,这种情况下,等价于这个变量声明在每个case clause隐式代码块的开始位置。如果case clause只列出了一个类型,则变量的类型就是这个类型,否则就是原始值的类型。
假设下面的例子中x的类型为x interface{}
switch i := x.(type) {
case nil:
printString("x is nil") // i的类型是 x的类型 (interface{})
case int:
printInt(i) // i的类型 int
case float64:
printFloat64(i) // i的类型是 float64
case func(int) float64:
printFunction(i) // i的类型是 func(int) float64
case bool, string:
printString("type is bool or string") // i的类型是 x (interface{})
default:
printString("don't know the type") // i的类型是 x的类型 (interface{})
}
也许你已经看到上面的例子中有一个case clause中的类型是nil,它用来匹配x为nil的interface{}的情况。
实际的例子解析使用
package main
import "log"
//创建动物接口,内部定义唱歌,跳函数
type animal interface {
sing()
jump()
}
//创建一个狗结构体,实现唱歌和跳函数
//狗结构体对象中,只有都实现了上述动物的内部定义,才能成功将狗定义为动物
type dog struct{}
func (m *dog) sing() {
log.Println("dog sing")
}
func (m *dog) jump() {
log.Println("dog jump")
}
func Judge(c interface{}) bool {
ty, ok := c.(animal)
log.Println("ty:", ty)
return ok
}
func main() {
m := new(dog)//这里要用new申请新地址实现这个,不能使用下列这种方法
//m := dog{} 这样得到的是一个空的dig对象,输出的是
//2020/02/12 17:03:31 ty: <nil>
//2020/02/12 17:03:31 false
ok := Judge(m)
log.Println(ok)
}
结果显示:
2020/02/12 16:54:04 ty: &{}
2020/02/12 16:54:04 true
参考文献https://colobu.com/2016/06/21/dive-into-go-6/#%E7%B1%BB%E5%9E%8B%E6%96%AD%E8%A8%80_type_assertion
有疑问加站长微信联系(非本文作者)