0
点赞
收藏
分享

微信扫一扫

GO语言学习之路18

心智的年轮 2022-02-11 阅读 40
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)
}
举报

相关推荐

0 条评论