美文网首页golang
Go接口类型的使用

Go接口类型的使用

作者: 喜龙爱慧 | 来源:发表于2017-05-03 15:33 被阅读722次

    定义接口

    type Namer interface {
        Method1(param_list) return_type
        Method2(param_list) return_type
        ...
    }
    

    基础知识

    1. 接口不能包含变量,只能定义一组抽象的方法集合。
    2. 类型不需要显式声明它实现了某个接口:接口被隐式地实现。只要类型实现了接口包含的所有抽象方法。那么该类型便属于该接口的实现类
    3. 多个类型可以实现同一个接口,一个类型可以实现多个接口
    4. 接口可以嵌套接口。
    5. **声明一个 interface{} 空接口,可接收任何类型。例如:万能切片 []interface{},任意Map map[string]interface{} **。

    多态

    //利用接口实现多态
    type IAnimal interface {
        Eat()
    }
    
    type Dog struct {
        name string
    }
    
    func (this *Dog) Eat()  {
        fmt.Printf("%v 吃 %v\n", this.name, "狗粮")
    }
    
    type Cat struct {
        name string
    }
    
    func (this *Cat) Eat()  {
        fmt.Printf("%v 吃 %v\n", this.name, "猫粮")
    }
    
    func TestIAnimal(t *testing.T)  {
        //定义一个IAnimal接口类型的切片
        anims := []IAnimal{&Dog{"旺财"}, &Cat{"咖啡猫"}}
        for n, _ := range anims {
            anims[n].Eat()
        }
        //旺财 吃 狗粮
        //咖啡猫 吃 猫粮
    }
    

    接口嵌套接口

    type IA interface {
        AFun()
    }
    
    type IB interface {
        BFun()
    }
    
    //接口可以嵌套接口
    type IAB interface {
        IA
        IB
        ABFun()
    }
    
    type AB struct {
        name string
    }
    
    func (this *AB) AFun() {
        fmt.Println(this.name + " is A Fun")
    }
    
    func (this *AB) BFun() {
        fmt.Println(this.name + " is B Fun")
    }
    
    func (this *AB) ABFun() {
        fmt.Println(this.name + " is AB Fun")
    }
    
    type BA struct {
        name string
    }
    
    func (this *BA) AFun() {
        fmt.Println(this.name + " is A Fun")
    }
    
    func (this *BA) BFun() {
        fmt.Println(this.name + " is B Fun")
    }
    
    func (this *BA) ABFun() {
        fmt.Println(this.name + " is AB Fun")
    }
    
    func TestIAB(t *testing.T) {
        //AB和BA结构体都实现了IA、IB、IAB接口
        abs1 := []IA{&AB{"AB"}, &BA{"BA"}}
        for n, _ := range abs1 {
            abs1[n].AFun()
        }
        //AB is A Fun
        //BA is A Fun
        abs2 := []IB{&AB{"AB"}, &BA{"BA"}}
        for n, _ := range abs2 {
            abs2[n].BFun()
        }
        //AB is B Fun
        //BA is B Fun
        abs3 := []IAB{&AB{"AB"}, &BA{"BA"}}
        for n, _ := range abs3 {
            //既可以使用嵌套接口声明的函数,也可以使用本接口声明的函数。
            abs3[n].AFun()
            abs3[n].ABFun()
        }
        //AB is A Fun
        //AB is AB Fun
        //BA is A Fun
        //BA is AB Fun
    }
    

    类型断言

    类型断言即Comma-ok断言。写法为 value, ok := em.(T)

    • em:要判断的变量,em必须是interface类型
    • T:被判断的类型;
    • value:返回的值;
    • ok:是否为该类型;
    func TestCD(t *testing.T) {
        cd := &CD{}
        //如果变量cd没有转换成interface{}类型,报如下错误:
        //invalid type assertion: cd.(IA) (non-interface type *CD on left)
        if _, ok := interface{}(cd).(IA); !ok {
            fmt.Println("没有实现")
        }
    
        a := &AB{"AB"}
        if v, ok := interface{}(a).(IA); ok {
            v.AFun()
        }
    }
    

    相关文章

      网友评论

        本文标题:Go接口类型的使用

        本文链接:https://www.haomeiwen.com/subject/mwiodttx.html