Go:类型断言

一、基本介绍

类型断言:由于接口是一般类型,不知道具体类型,如果要转成具体类型,就需要使用类型断言。

如果希望将一个空接口类型重新转换成对应的类型,那么需要使用类型断言,能转换成功是因为这个空接口原先是指向这个类型的。

type Point struct {
	x int
	y int
}

func main() {
	var a interface{}
	var p = Point{1, 2}
	a = p // 这是可以的
	var b Point
	//b = a // 这时不可以的,要使用断言,如下
	b = a.(Point) // 这就是类型断言,表示看看能不能将 a 转换成 Point,再赋给 b
	c := a.(Point)
	fmt.Println(b) // {1 2}
	fmt.Printf("c的类型=%T,值=%v", c, c) // c的类型=main.Point,值={1 2}
}

二、带检测的类型断言

在进行类型断言时,如果类型不匹配,就会报 panic,因此在进行类型断言时,需要检测机制,如果成功就继续执行,否则不要报 panic。

type Point struct {
	x int
	y int
}

func main() {
	var a interface{}
	var p = Point{1, 2}
	a = p
	b, ok := a.(int) // 肯定转换失败的,如果是string,则 b 为空
	if ok{
		fmt.Println("转换成功")
	} else {
		fmt.Println("转换失败") // 转换失败
	}
	fmt.Println(b) // 0
}

三、类型断言最佳实践

示例1:

type Usb interface {
    Connect()
    Disconnect()
}

type Phone struct {Name string}
type Camera struct {Name string}
func (p Phone) Connect() {fmt.Printf("%s连接中...\n", p.Name)}
func (p Phone) Disconnect() {fmt.Printf("%s断开连接中...\n", p.Name)}
func (c Camera) Connect() {fmt.Printf("%s连接中...\n", c.Name)}
func (c Camera) Disconnect() {fmt.Printf("%s断开连接中...\n", c.Name)}
// Phone结构体特有的方法Call
func (p Phone) Call() {fmt.Printf("正在使用%s打电话,..\n", p.Name)}

type Computer struct {}
func (c Computer) Working(usb Usb) {
    usb.Connect()
    usb.Disconnect()
    // 如果 usb 是指向 Phone 结构体变量,则还需要调用 Call 方法
    phone, ok := usb.(Phone) // 类型断言
    if ok {
        phone.Call()
    }
}

func main() {
    // 定义一个 Usb 接口数组,可以存放 Phone 和 Camera 结构体的实例
    var usbArr [2]Usb
    usbArr[0] = Phone{"苹果"}
    usbArr[1] = Camera{"尼康"}
    var computer Computer
    for _, v := range usbArr {
        computer.Working(v)
    }
    fmt.Println()
    fmt.Println(usbArr)
}
View Code

示例2:

type Student struct {}

func TypeJudge(args... interface{}) {
    for i, v := range args {
        switch v.(type) {
            case int, int8, int16, int32, int64:
                fmt.Printf("第%v个参数是 整数 类型,值是%v\n", i, v)
            case float32:
                fmt.Printf("第%v个参数是 float32 类型,值是%v\n", i, v)
            case float64:
                fmt.Printf("第%v个参数是 float64 类型,值是%v\n", i, v)
            case bool:
                fmt.Printf("第%v个参数是 bool 类型,值是%v\n", i, v)
            case string:
                fmt.Printf("第%v个参数是 string 类型,值是%v\n", i, v)
            case Student:
                fmt.Printf("第%v个参数是 Student 类型,值是%v\n", i, v)
            case *Student:
                fmt.Printf("第%v个参数是 *Student 类型,值是%v\n", i, v)
            default:
                fmt.Printf("第%v个参数的类型未知,值是%v\n", i, v)
        }
    }
}

func main() {
    var a int = 1
    var b float32 = 2.2
    var c float64 = 3.3
    var d bool = true
    var e Student
    var f *Student
    TypeJudge(a, b, c, d, e, f)
}
View Code

 

posted @ 2019-05-29 19:24  就俗人一个  阅读(826)  评论(0编辑  收藏  举报