Go语言接口(interface{})类型断言

Go语言接口类型断言

1,使用场景

1.1,检查接口类型变量的值是否实现了期望的接口。
    理解:
        * 很简单,就是检查当前接口类型的值有没有实现指定的某个具体的接口。
1.2,把接口类型变量的值转换为其他类型或其他接口。
    理解:
        * 其实很好理解,go语言空interface{}可以保存任何类型的变量,
        当程序中需要使用该变量的时候,需要把接口类型变量的值转化为
        具体类型,可以通过接口类型断言。
        * 假如接口类型保存的值是数字,当前的值要参与数学运算,就必须
        转为int类型才可以参加运算,这就是利用接口断言来实现类型转换的例子。

注意:
    被断言的对象必须是接口类型,否则会报错

2,断言格式

1,t := i.(T)  

    * 断言成功,则t为T类型的接口值
    * 断言失败则报错,panic

2,v,ok := i.(T)      

    * 断言成功,则v为T类型的接口值,ok为true
    * 断言失败,则v为空值,ok为false

3,type-switch

    switch 接口变量.(type) {
        case 类型1:
            // 变量是类型1时的处理
        case 类型2:
            // 变量是类型2时的处理
        case nil :
            // 空接口进入此流程
        …
        default:
            // 变量不是所有case中列举的类型时的处理
    }

    假如断言的类型同时实现了switch断言的多个case,取第一个case


4,注意:
    * 接口变量的值转类型很简单,断言出的结果就是该类型
    * 接口A变量的值转接口B类型的时候,断言出来的结果就是B接口类型的变量。相应的只能调用B接口的方法

3,代码实例

1,直接断言格式

1,格式:

    t := i.(T)  
    v,ok := i.(T)

2,代码:

    1,接口转类型

        var i interface{}
        i = 10
        v,ok := i.(int)
        fmt.Println(v,ok)
        v2 := i.(int)
        fmt.Println(v2)

    2,接口转接口

        package interfaceDemo

        import (
            "fmt"
        )

        type Walker interface {
            Walk()
        }

        type Swimer interface {
            Swim()
        }

        type dog struct {
        }

        func (d *dog) Walk() {
            fmt.Println("Dog avalible Walk")
        }

        type duck struct {
        }

        func (d *duck) Walk(){
            fmt.Println("Duck avalible Walk")
        }

        func (d *duck) Swim(){
            fmt.Println("Duck avalible Swim")
        }

        func Run() {
            var w interface{}
            w = new(duck)
            v,ok := w.(Swimer)
            fmt.Println(v,ok)
            v.Swim()

            v1,ok1 := w.(Walker)
            fmt.Println(v1,ok1)
            v1.Walk()

            v2,ok2 := w.(*Duck)
            v2.Walk()
            v2.Swim()
            fmt.Println(v2,ok2)
            //注意:
                * w变量虽然保存了duck结构体实力,但类型不是结构体,
                  所以也就不能调用duck接口体方法。

                * v变量是Swimer接口类型的变量,所以只能调用Swimer下的方法。
                  不能调用Walker接口下的方法,虽然duck结构体实现了Walker接口

                * 相应的v1是Walker接口类型的变量,只能调用Walker的方法,
                  不能调用Swimer的方法

                * 如果w接口类型的值要同时可以调用Walk和Swim,可以将w类型断言为结构体duck
                  的指针类型,如上面v2类型的断言

                * 上面的流程: 
                    w接口类型赋值,
                    然后转w接口类型的值的类型为Swimer接口类型
                    然后转w接口类型的值的类型为Walker类型
                    然后转w接口类型的值的类型为结构体duck的指针类型

        }

2,type-switch断言格式

func Run() {
    var w interface{}
    w = new(Duck)
    AssetType(w)
    //这里只输出Type is Swimer。
    //假如断言的类型同时实现了switch断言的多个case,取第一个case。

    var x interface{}
    x = 10
    AssetType(x)

    //空接口为nil
    var y interface{}
    AssetType(y)
}


func AssetType(data interface{}){
    switch data.(type){
        case Swimer :
        fmt.Println("Type is Swimer")
        case Walker :
        fmt.Println("Type is Walker")
        case int:
        fmt.Println("Type is int")
        case string:
        fmt.Println("Type is string")
        case bool :
        fmt.Println("Type is bool")
        case nil :
        fmt.Println("Type is nil")
        default:
        fmt.Println("Type Not Found")
    }
}
  • 1
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值