2022/02/09
//今天就这么多吧,顶不住了,睡觉保狗命!
package main
import "fmt"
/*
断言
*/
type Point struct {
x int
y int
}
type nilInterface interface{}
func main() {
var point Point = Point{1, 2}
var x nilInterface
/*
空接口还可以直接用
var x interface{}
*/
x = point //空接口可以接收任意类型的值
//如果想知道 x 是不是nilInterface类型,需要用到断言
y := x.(nilInterface) //如果转换成功就成功,不成功就报错
fmt.Println(y) // output: {1 2}
/*
如何使用带检测的断言,如果转换成功,就继续运行,
如果转换失败,就不转换继续运行下面的代码
*/
p, ok := x.(int)
if ok {
fmt.Println("转换成功")
fmt.Printf("p的类型是 %T, 值是%v\n", p, p)
} else {
fmt.Println("转换失败")
}
/* 上面的判断等价于
if p,ok := x.(int); ok {
fmt.Println("转换成功")
fmt.Printf("p的类型是 %T, 值是%v\n", p, p)
} else {
fmt.Println("转换失败")
}
*/
fmt.Println("转换失败后依旧不影响后面的代码运行")
z := x.(int)
fmt.Println(z) // output: panic: interface conversion: main.nilInterface is main.Point, not int
}
package main
/*
来一个类型断言的经典案例1
*/
import "fmt"
/*
问题来了,如果Phone定义有一个Call()方法,但是Camaro并没有这个方法
那么我们在Computer中调用的时候如何判断传入的Usb接口是Phone类型还是Camaro类型呢
需要使用断言,详情看代码
*/
//声明一个接口
type Usb interface {
//声明了两个没有实现的方法
start()
stop()
}
type Phone struct {
}
//让phone实现USB接口的方法
func (p Phone) start() {
fmt.Println("手机开始工作...")
}
func (p Phone) stop() {
fmt.Println("手机停止工作...")
}
func (p Phone) Call() {
fmt.Println("手机打电话...")
}
type Camaro struct {
}
//让相机实现USB接口的方法
func (c Camaro) start() {
fmt.Println("相机开始工作...")
}
func (c Camaro) stop() {
fmt.Println("相机停止工作...")
}
//计算机
type Computer struct {
}
//编写一个方法Working方法,接收一个usb接口类型变量
//只要是实现了USB接口(就是指实现了Usb接口声明的所有方法)
func (c Computer) Working(usb Usb) {
//通过USB接口变量来调用start和stop方法
//在这里判断,如果传入的是Phone,也要调用Call()方法
usb.start()
/*
如果我们这里直接调用usb.Call()方法,万一传入的是Camaro
就没有这个方法,不是要panic了么
*/
if p, ok := usb.(Phone); ok {
p.Call()
}
usb.stop()
}
func main() {
//测试
var computer Computer = Computer{}
var phone Phone = Phone{}
var camaro Camaro = Camaro{}
//关键点
computer.Working(phone)
computer.Working(camaro)
}
package main
import "fmt"
/*
来一个类型断言的经典案例2
写一个函数,循环判断传入参数的类型
*/
type MyStruct struct {
}
//...表示函数TypeJudge可以接收任意多个实参
//interface{}表示函数TypeJudge可以接收任意类型的实参
//Items ...interface{} 表示函数TypeJudge可以接收任意多个任意类型的实参
func TypeJudge(Items ...interface{}) {
for i, x := range Items {
switch x.(type) { //这里type是一个关键字,固定写法
case bool:
fmt.Printf("param #%d is a bool 值是%v\n", i, x)
case float64:
fmt.Printf("param #%d is a float64 值是%v\n", i, x)
case int, int32, int64:
fmt.Printf("param #%d is a int 值是%v\n", i, x)
case string:
fmt.Printf("param #%d is a string 值是%v\n", i, x)
case nil:
fmt.Printf("param #%d is a nil 值是%v\n", i, x)
case MyStruct:
fmt.Printf("param #%d is a nil 值是%v\n", i, x)
case *MyStruct:
fmt.Printf("param #%d is a nil 值是%v\n", i, x)
default:
fmt.Println("不知道这是个什么类型")
}
}
}
func main() {
// var n1 float32 = 1.1
// var n2 float64 = 2.2
// var n3 int32 = 1
// var n4 string = "smx"
// var n5 bool = true
//还可以判断自定义类型
var myS MyStruct
var myS2 *MyStruct //指针为空,nil
var myS3 *MyStruct = &MyStruct{}
TypeJudge(6, "ert", 1.2, true, myS, myS2, myS3)
}