公众号merlinsea
- 使用场景
- 接口转其他数据类型的时候需要使用类型断言才能转,不能使用强转的方法将接口转为其他数据类型。
- 当需要调用接口原本指向结构体中特有的方法的时候也会用到类型断言。
- 断言的方式转其他数据类型有两种分类
- 不带检测的断言,如果不能转成功会报panic,导致整个程序结束
- 带检测的断言【推荐】
type Point struct { x int y int } func main() { var a interface{} var point Point = Point{1, 2} a = point //oK var b Point b = a.(Point) //b = Point(a) 基本数据类型之间可以进行强转,但接口转其他类型只能采用断言的方式 fmt.Println(b) //类型断言的其它案例 var x interface{} var b2 float32 = 1.1 x = b2 //空接口,可以接收任意类型 // x=>float32 [使用类型断言] y := x.(float32) fmt.Printf("y 的类型是 %T 值是=%v", y, y) //类型断言(带检测的) var z interface{} var b3 float32 = 2.1 z = b3 //空接口,可以接收任意类型 // x=>float32 [使用类型断言] //类型断言(带检测的) if y, ok := z.(float32); ok { fmt.Println("convert success") fmt.Printf("y 的类型是 %T 值是=%v", y, y) } else { fmt.Println("convert fail") } fmt.Println("继续执行...") }
- 类型断言应用在需要掉接口指向结构体的特有方法的场景
//声明/定义一个接口 type Usb interface { //声明了两个没有实现的方法 Start() Stop() } type Phone struct { name string } //让Phone 实现 Usb接口的方法 func (p Phone) Start() { fmt.Println("手机开始工作。。。") } func (p Phone) Stop() { fmt.Println("手机停止工作。。。") } func (p Phone) Call() { fmt.Println("手机 在打电话..") } type Camera struct { name string } //让Camera 实现 Usb接口的方法 func (c Camera) Start() { fmt.Println("相机开始工作。。。") } func (c Camera) Stop() { fmt.Println("相机停止工作。。。") } type Computer struct { } func (computer Computer) Working(usb Usb) { usb.Start() //如果usb是指向Phone结构体变量,则还需要调用Call方法 //类型断言,当需要掉结构体特有方法的时候,必须使用类型断言进行转换 if phone, ok := usb.(Phone); ok { phone.Call() } usb.Stop() } func main() { //定义一个Usb接口数组,可以存放Phone和Camera的结构体变量 //这里就体现出多态数组 var usbArr [3]Usb usbArr[0] = Phone{"vivo"} usbArr[1] = Phone{"小米"} usbArr[2] = Camera{"尼康"} var computer Computer for _, v := range usbArr{ computer.Working(v) fmt.Println() } }
- 通过断言类判断任意的数据类型【项目开发中使用】
- 判断函数的形参必须是空接口类型来进行接收,这样才具有通用性
- 结构体和结构体指针类型不是同一种类型。
//定义Student类型 type Student struct { } //判断一个输入的参数是什么类型,这里我们的形参接受类型必须是空接口类型!! func TypeJudge(items ...interface{}) { for index, x := range items { switch x.(type) { case bool: fmt.Printf("第%v个参数是 bool 类型,值是%v\n", index, x) case float32: fmt.Printf("第%v个参数是 float32 类型,值是%v\n", index, x) case float64: fmt.Printf("第%v个参数是 float64 类型,值是%v\n", index, x) case int, int32, int64: fmt.Printf("第%v个参数是 整数 类型,值是%v\n", index, x) case string: fmt.Printf("第%v个参数是 string 类型,值是%v\n", index, x) case Student: fmt.Printf("第%v个参数是 Student 类型,值是%v\n", index, x) case *Student: fmt.Printf("第%v个参数是 *Student 类型,值是%v\n", index, x) default: fmt.Printf("第%v个参数是 类型 不确定,值是%v\n", index, x) } } } func main() { var n1 float32 = 1.1 var n2 float64 = 2.3 var n3 int32 = 30 var name string = "tom" address := "北京" n4 := 300 stu1 := Student{} stu2 := &Student{} TypeJudge(n1, n2, n3, name, address, n4, stu1, stu2) }