×

接口 interface-GOLANG

96
与子笑
2018.05.20 10:32 字数 881

golang  @amazeUI  2017-10-10 22:50:55

//func main() {

//    var a TT

//    a.adds(100)

//    fmt.Println(a)

//}

//func (a *TT) adds(num int) { //为TT类型绑定一个method

//    *a += TT(num) //这里虽然也是int,但是还是不一样,至于为什么不一样以后再做研究

//    //不转成TT类型会报错

//}

//以上是上篇博文该写的。

type USB interface { //定义一个接口

    Name()

    Connect()

}

type USBa interface { //定义一个接口做Disconnect测试

    Name()

    Connecte

}

type Connecte interface { //嵌入到USBa当中

    Connect()

}

type PC struct {

    name string

}

func (a PC) Name() {

    fmt.Println(a.name)

}

func (a PC) Connect() {

    fmt.Println("已成功连接pc", a.name)

}

type Phone struct { //定义一个结构体,可以简单的理解为php里的类

    name string

}

func (a Phone) Name() { //将Name方法绑定到a这个结构体中

    fmt.Println(a.name)

}

func (a Phone) Connect() { //同时将connect绑定到这个结构体中

    //只要这个结构体绑定了某个接口的所有方法,则默认实现了该接口,若定一个没有方法的结构则默认所有结构都实现了该结构

    fmt.Println("已成功连接上您的:", a.name)

}

func main() {

    var a USB

    a = Phone{"iphone"} //实现一个结构体定义其name,在这里可以简单的理解为a是实现了一个接口的对象

    a.Name()

    a.Connect()

    //上面可以简写为以下代码

    //a:=Phone{"iphone"}但是这样并不直观,因为并不知道这个a是否实现了USB接口,如果没有实现

    //那必然调用不了该接口的所有方法,所以我们需要一个检测是否实现了该接口的方法disconnect

    var b USBa

    b = PC{"smartisan"}

    Disconnect(b)

}

func Disconnect(usb USBa) { //做一个断开连接的方法,要求传进来一个实现了usba接口的结构

    if st, ok := usb.(PC); ok { //这里可以简单的理解为接收到一个实现了usba的结构

        //这种模式叫ok pattern

        //传进来一个结构体,可以看到这个结构体有没有实现该接口,ok返回状态st为该实例

        fmt.Println("已断开您的", st.name) //能走到这里说明已经能取到st的name了而usb接口这一层是没有name这个属性的

    }

} //这里有点想不明白既然传进来的必须是一个已经实现了该接口应该是没必要再做一个disconnect以近乎一种

//类似与一个杯子非要等装满水后才能判断这个杯子可不可以装水。经过测试没有实现该接口而穿进来一个结构体的话是会报错的

//讲道理的话代码应当如下

//type Stringer interface {

//    String() string

//}

//if sv, ok := v.(Stringer); ok {

//    fmt.Printf("v implements String(): %s\n", sv.String()) // note: sv, not v

//}//disconnect的传入类型必须是一个结构体抑或是一个空接口才合理!下面是一个type switch判断该结构实现了哪种接口

func Disconnect_Type_Switch(usb interface{}) {

    switch v := usb.(type) {

    case Phone:

        fmt.Println(v.name)

    case PC:

        fmt.Println(v.name)

    default:

        fmt.Println("两个接口都没有实现")

    }

}

//当对象赋值给接口时,假设该对象已有字段值,再修改对象的该字段值,并不会影响该实现了该接口的对象的字段值

//也就是说当对象赋值给接口时,是将对象的字段值完整的拷贝到该接口的变量上的

PHP01.COM
Web note ad 1