开发者学堂课程【Go 语言核心编程 - 面向对象、文件、单元测试、反射、TCP 编程:类型断言引出和基本使用】学习笔记,与课程紧密联系,让用户快速学习知识。
课程地址:https://developer.aliyun.com/learning/course/626/detail/9706
类型断言引出和基本使用
内容介绍:
一、 类型断言的引出
二、 类型断言的基本介绍和基本使用
一、类型断言的引出
1.类型断言的引出
讲多态数组时提到:、给Usb数组中,存放Phone结构体和Camera结构体变量,Phone还有一个特有的方法call(),请遍历Usb数组,如果是Phone变量,除了调用Usb接口声明的方法外,还需要调用Phone特有方法call。
例如:
//编写一个方法Working方法,接收一个Usb接口类型变量
//只要是实现了Usb接口(所谓实现 Usb接口,就是指实现了Usb 接口声明所有方法)
func (c Computer) Working(usb Usb) { //usb变量会根据传入的实参,来判断到底是Phone,还是Camera
//通过usb接口变量来调用Start和Stop方法
usb .Start()
usb .Stop()
}
func main() {
//测试
//先创建结构体变量
computer := Computer{ }
phone := Phone{ }
camera := Camera{ }
}
不能用usb.Call()来调用,代码如下:
//编写一个方法Working方法,接收一个Usb接口类型变量
//只要是实现了Usb 接口(所谓实现 Usb接口,就是指实现了Usb 接口声明所有方法)
func (c Computer) Working(usb Usb) { //usb变量会根据传入的实参,来判断到底是Phone,还是Camera
//通过usb接口变量来调用Start 和Stop方法
usb.Start()
usb.Call()
usb. Stop()
}
因为传进的usb可能是Camera也可能是Phone,Phone里面有一个特定方法call(),但是Camera没有,所以需要用类型断言判断传进的结构体变量usb是Camera还是Phone。
2.由具体需要引出类型断言。
类型断言快速引入案例:
例如:
type Point struct {
x int
y int
}
func main() {
var a interface()
var point Point = Point(1, 2)
a = point
//此式正确,因为a是一个空接口,空接口可以接收任意一个变量,所以把point赋值给a正确
//如何将a赋给 Point变量?
var b Point
b=a//不正确
fmt.PrintIn(b)
}
需求:如何将一个接口变量,赋给自定义类型的变量。从而引出类型断言。
解决方法:
新建一个名为 assert 的文件夹,新建一个名为main.go的文件,程序代码:
package main
import(
“fmt”
type Point struct{
x int
y int
func main() {
var a interface{ }
var point Point = Point{1, 2}
a=point
var b Point
b = a.(Point)//类型断言
fmt.Println(b)
}
运行结果:{1 2}
b = a.(Point)
就是类型断言,表示判断a是否指向Point类型的变量,如果是就转成Point类型并赋值给b变量,否则报错。
二、类型断言的基本介绍和基本使用
1.基本介绍:
类型断言,由于接口是一般类型,不知道具体类型,如果要转成具体类型,就需要使用类型断言,具体如下:
//float32可以是其它类型,比如Point
var t float32
var x interface{}
x=t
//转成float,带检查的
y,ok:=x.(float32)
if ok == true {
fmt.PrintIn(“convert success”)
} else {
fmt.Println(“convert fail”)
}
2.类型断言的其它案例:
var x interface{}
var b2 float32 = 1.1
x=b2 //空接口,可以接收任意类型
//x=>float32 [使用类型断言]
y := x.(float32) //此处不可随意转换,需清楚x指向的什么类型,才可以转回来
fmt.Printf(“y的类型是 %T值是=%v”,y,y)
结果是:y的类型是float32 值是-1,1
对上面代码的说明:
(1)在进行类型断言时,如果类型不匹配,就会报panic,因此进行类型断言时,要确保原来的空接口指向的就是断言的类型
(2)如何在进行断言时,带上检测机制,如果成功就OK,否则也不要报panic。
3.带检测的类型断言案例:
案例(1):
var x interface{}
var b2 float32 =1.1
x = b2 //空接口,可以接收任意类型
// x=>float32[使用类型断言]
//类型断言(带检测的)
y,ok:= x.(float64) //如果成功ok就返回True,如果失败返回False。但是代码仍然可以继续执行。
if ok == true{ //此处可简化为if ok
fmt.Println(“convert success”)
fmt.Printf(“y 的类型是%T值是=%v”,y,y)
}else {
fmt.Println(“convert fail”)
}
fmt.Println(“继续执行...”)
}
运行结果:convert fail
继续执行…
案例(2):
var x interface{}
var b2 float32 =1.1
x = b2 //空接口,可以接收任意类型
// x=>float32[使用类型断言]
//类型断言(带检测的)
y,ok:= x.(float32)
//本句和下句可简化为 if y, ok := x.(float32);ok{
if ok == true{
//此处可简化为if ok
fmt.Println(“convert success”)
fmt.Printf(“y 的类型是%T值是=%v”,y,y)
}else {
fmt.Println(“convert fail”)
}
fmt.Println(“继续执行...”)
}
运行结果:convert success
y的类型是 float32 值是=1.1继续执行…
}
案例(3):
var x interface{}
var b2 float32 =2.1
x = b2 //空接口,可以接收任意类型
// x=>float32[使用类型断言]
//类型断言(带检测的)
y,ok:= x.(float32) //本句和下句可简化为 if y, ok := x.(float32);ok{
if ok == true{ //此处可简化为if ok
fmt.Println(“convert success”)
fmt.Printf(“y 的类型是%T值是=%v”,y,y)
}else {
fmt.Println(“convert fail”)
}
fmt.Println(“继续执行...”)
}
运行结果:convert success
y的类型是 float32 值是=2.1继续执行…
}