go学习笔记 - 接口

接口是golang最重要的特性之一,在Go中,接口interface其实和其他语言的接口意思没什么区别。interface理解其为一种类型的规范或者约定。一种类型是不是“实现”了一个接口呢?就看这种类型是不是实现了接口中定义的所有方法。接⼝是一个或多个方法签名的集合,任何非接口类型只要拥有与之对应的全部方法实现 (包括相同的名称、参数列表以及返回值。),就表示它"实现" 了该接口,无需显式在该类型上添加接口声明。


go的接口和定义

  • 接口实现是隐式的,只需要实现里的全部方法(方法的参数和返回值类型要一致)
  • 接口由使用者来定义

go接口使用:

调用者  : 

// 使用者定义接口及接口内的方法
type Retriever interface {
    Get(url string) string
}

// 使用者定义使用接口的方法
func download(r Retriever) string{
    return r.Get("this is a get func")
}


实现者:

// 实现者定义一个类型
type MyRetriever struct {
    Contents string
}

// 实现者实现接口内的get方法即可
func (r MyRetriever) Get(url string) string{   
    return r.Contents +","+ url
}    

main    
    

func main(){
    var r Retriever
    r = MyRetriever{"this is mytriever"}
    fmt.Println(download(r))
}

在这个例子中,使用者定义了接口和接口中的方法,实现者不需要显示实现接口,只需要实现接口中的全部方法(就代表隐式地实现了接口)

  • interface接口定义由使用者定义
  • 使用者想使用这个接口的get方法
  • 实现者完全不用管要实现哪个接口,只需要实现这个接口的方法即可


接口类型的判断

  • type switch 
  • type assertion

interface类型有 interface.(type)的方式            

    switch v := r.(type) {
    case MyRetriever:
        fmt.Println(v.Contents)
    }

    //或者 显示转化 type assertion
    myre := r.(MyRetriever)
    fmt.Println(myre.Contents)


    //或者严格版本的显示转化
    if MyRetriever, ok := r.(MyRetriever); ok{
        fmt.Println(MyRetriever.Contents)
    }else {
        fmt.Println("error")
    }


接口的组合

  • 接口的组合也是使用者定义,可以分开定义各个接口,也可以定义接口组合
  • 实现者实现接口,不管是怎么定义的,只管实现接口的方法即可。 

使用者


// 定义接口1
type Retriever interface {
    Get(url string) string
}
// 定义接口2
type Poster interface {
    Post(url string) string
}

// 定义接口3(接口1和接口2的组合,并且有自己的方法)
type RetrieverPoster interface {
    Retriever
    Poster
    Connect(str string) string
}

// 下面就是对上面三个接口的调用,参数分别是接口对象
func download(r Retriever) string{
    return r.Get("this is a get func")
}
func post(p Poster) string{
    return p.Post("this is a post func")
}
func retrieverPoster(s RetrieverPoster)   {
    s.Get("this is a get func of retrieverPoster")
    s.Post("this is a post func of retrieverPoster")
}

func main(){
    // 使用1
    var r Poster
    r = MyRetriever{"this is mytriever"}
    retrieverPoster(r)        // error
    post(r)                   // right

    // 使用2
    var re Retriever
    re = MyRetriever{"this is mytriever"}
    download(re)
    
    // 使用3
    rp := MyRetriever{"this is mytriever"}
    retrieverPoster(rp)      // right
    download(rp)             // right
}

实现者


//MyRetriever 实现了Retriever和Poster的接口,只需要实现这两个接口的方法即可
type MyRetriever struct {
    Contents string
}

func (r MyRetriever) Get(url string) string{
    fmt.Println(r.Contents +","+ url)
    return r.Contents +","+ url
}

func (r MyRetriever) Post(url string) string{
    fmt.Println(r.Contents +","+ url)
    return r.Contents +","+ url
}

func (r MyRetriever) Connect(url string) string{
    fmt.Println(r.Contents +","+ url)
    return r.Contents +","+ url
}

猜你喜欢

转载自blog.csdn.net/zengchen73/article/details/81195836