Go

在go语言中,也有接口的定义。但是和其他语言不同的是,go语言的接口比较“特殊”。。。

定义

接口是一个或者多个方法签名的集合,它之后方法的定义,没有方法的实现,也不能在其中定义字段。

// interface.go
package main

import (
    "fmt"
)

type IUSB interface {
    GetName() string
    Connect()
}

func main() {
    fmt.Println("Hello World!")
}

实现接口

在go语言中,通过定义类型来实现接口。实现接口的时候,无需显示指定实现了那个接口(这与其他语言不同),只需要定义出所需实现接口的所有方法即可。我们成这种方式为(Structural typing).

// interface.go
package main

import (
    "fmt"
)

type IUSB interface {
    GetName() string
    Connect()
}

type CellPhoneUSB struct {
    Name string
}

func (cp CellPhoneUSB) GetName() string {
    return cp.Name
}

func (cp CellPhoneUSB) Connect() {
    fmt.Println("cell phone connected...", cp.Name)
}

func main() {
    var a IUSB
    a = CellPhoneUSB{"myCellPhone"}
    a.Connect()
}

我们先看下输出结果:

可以看到,我们定义了一个类型是CellPhoneUSB,它实现了IUSB中的两个方法GetName()和Connect(). 

在main函数里面,我们定义了一个变量a,它的类型是接口IUSB,然后我们将a转换成为一个type(CellPhoneUSB),在此之后,我们调用了类型CellPhoneUSB的connect方法。

接口嵌套

当我们需要将明确接口的层次结构的时候,就需要使用接口的嵌套。例如

type Connector interface {
    Connect()
}

type IUSB interface {
    GetName() string
    Connector
}

类型判断

有时候,由于我们实现的类型是实现了某种嵌套的接口,这时就需要我们进行类型判断。 闲话少说,上code

// interface.go
package main

import (
    "fmt"
)

type Connector interface {
    Connect()
}

type IUSB interface {
    GetName() string
    Connector
}

type CellPhoneUSB struct {
    Name string
}

func (cp CellPhoneUSB) GetName() string {
    return cp.Name
}

func (cp CellPhoneUSB) Connect() {
    fmt.Println("cell phone connected...", cp.Name)
}

func Disconnect(connector Connector) {
    if pc, ok := connector.(CellPhoneUSB); ok {
        fmt.Println("disconnected ...", pc.Name)
    }
    fmt.Println("type unknown!")
}

func main() {
    var a IUSB
    a = CellPhoneUSB{"myCellPhone"}
    a.Connect()
    Disconnect(a)
}

我们定义了一个Disconnect的方法,在其中需要判断是否为指定的类型(CellPhoneUSB), 这里使用了表达式语句 

if pc, ok := connector.(CellPhoneUSB); ok { 
...
}

:= 的右边是 -> 类型实例.(期望类型)

空接口与type-switch

go语言允许我们使用空接口来模拟类似object类型的类型。此时,判断类型实现了那个接口就稍显复杂。不过我们可以用type-swtich语句来处理。

func GetType(obj interface{}) {
    switch result := obj.(type) {
    case CellPhoneUSB:
        fmt.Println("It is a cell phone usb", result.Name)
    default:
        fmt.Println("Unknown type...")
    }
}

使用接口的规则

1. 调用接口传入对象时,无论怎样定义,都是对象的 copy, 因此,无法改变原对象。

2. 只有当接口存储的类型和对象都为nil时,接口才等于nil。



原文地址:https://www.cnblogs.com/atuotuo/p/7048778.html