• 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连接中...
    ", p.Name)}
    func (p Phone) Disconnect() {fmt.Printf("%s断开连接中...
    ", p.Name)}
    func (c Camera) Connect() {fmt.Printf("%s连接中...
    ", c.Name)}
    func (c Camera) Disconnect() {fmt.Printf("%s断开连接中...
    ", c.Name)}
    // Phone结构体特有的方法Call
    func (p Phone) Call() {fmt.Printf("正在使用%s打电话,..
    ", 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
    ", i, v)
                case float32:
                    fmt.Printf("第%v个参数是 float32 类型,值是%v
    ", i, v)
                case float64:
                    fmt.Printf("第%v个参数是 float64 类型,值是%v
    ", i, v)
                case bool:
                    fmt.Printf("第%v个参数是 bool 类型,值是%v
    ", i, v)
                case string:
                    fmt.Printf("第%v个参数是 string 类型,值是%v
    ", i, v)
                case Student:
                    fmt.Printf("第%v个参数是 Student 类型,值是%v
    ", i, v)
                case *Student:
                    fmt.Printf("第%v个参数是 *Student 类型,值是%v
    ", i, v)
                default:
                    fmt.Printf("第%v个参数的类型未知,值是%v
    ", 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

  • 相关阅读:
    2.16 C++类与new和delete操作符
    2.15 C++常量指针this
    2.14 C++析构函数
    2.13 C++拷贝构造函数
    2.12 C++ explicit关键字详解
    2.11 C++转型构造函数
    2.10 C++利用构造函数限制对象的创建
    2.9 C++使用默认参数的构造函数
    2.8 C++参数初始化表
    linux 查看进程启动路径
  • 原文地址:https://www.cnblogs.com/believepd/p/10945700.html
Copyright © 2020-2023  润新知