美文网首页
golang-接口

golang-接口

作者: 爱吃豆包 | 来源:发表于2019-12-17 20:30 被阅读0次

    Go语言规定,只要实现了接口里面的方法,就是该接口的实现类

    接口变量里面有什么?
    实现者的类型 和 实现者的指针
    
    接口变量自带指针
    接口变量同样采用值传递,几乎不需要使用接口的指针
    指针接收者实现只能以指针方式使用;值接收者都可以用
    

    定义一个接口

    package main
    
    import (
        "fmt"
        "interfaces/mock"
        "interfaces/real"
        "time"
    )
    
    /**
        Go语言规定,只要实现了接口里面的方法,就是该接口的实现类
    
        接口变量里面有什么?
        实现者的类型 和 实现者的指针
    
        接口变量自带指针
        接口变量同样采用值传递,几乎不需要使用接口的指针
        指针接收者实现只能以指针方式使用;值接收者都可以用
        
        。。。。
        type Retriever struct {}
        type Retriever string
        等等,都可以算是这个 Retriever 接口的实现类
        。。。。
    
     */
    
    // 声明一个接口类型
    type Retriever interface {
        // Get方法
        // 一个未实现的方法
        Get(url string) string
    }
    
    func download(r Retriever) string {
        return r.Get("http://www.imooc.com")
    }
    
    func main() {
        // 声明接口类型,但不分配内存
        var r Retriever
        // 获取 一个实现类,并赋值给 r
        // 因为 mock.Retriever 实现了 Retriever 接口里的方法,所以他就是一个实现类
        // 这里相当于就是把 mock.Retriever 值复制了一份,然后赋值给 r
        r = mock.Retriever{"这是一个百度网页"}
    
        // 输出是什么类型,也就是实现类型,以及值
        fmt.Printf("%T %v\n",r ,r)
    
        // 什么接口类型, 但不分配内存
        var rb Retriever
        // 实现类
        // 不建议使用接口指针,因为本身就自带了指针, 可以直接用指针
        rb = &real.Retriever{
            UserAgent: "Mozilla/5.0",
            TimeOut: time.Minute,
        }
    
        // 输出是什么类型,也就是实现类型,以及值
        fmt.Printf("%T %v\n",rb ,rb)
    
        //fmt.Println(download(r))
        //fmt.Println(download(rb))
    
        // 判断是什么类型
        inspect(rb)
    
        // 类型断言
        // 如果是指针就要用指针, 普通的就直接用,比如:mock.Retriever
        realRetriever, ok := r.(*real.Retriever)
        if ok {
            fmt.Println(realRetriever.TimeOut)
        } else {
            fmt.Println("这不是 mock.Retriever 类型")
        }
    
    
    }
    
    // 判断是什么类型
    func inspect(r Retriever)  {
    
        // 判断是什么样的类型
        switch v := r.(type) {
        case mock.Retriever:
            fmt.Println("Contents: ", v.Contents)
        case *real.Retriever:
            fmt.Println("UserAgent: ", v.UserAgent)
    
        }
    }
    
    
    

    接口实现1

    package mock
    
    /**
        这里是一个实现类,结构名称最好和那个接口名称一样
        然后在实现那个接口里面的 Get 方法
    
        Go语言规定,只要实现了接口里面的方法,就是该接口的实现类
    
     */
    
    type Retriever struct {
        // 结构体里面的属性
        Contents string
    }
    
    // 实现接口 Retriever 里面的方法 Get
    func (r Retriever) Get(url string) string {
        // 实现的方法体
        return r.Contents
    }
    
    

    接口实现 2

    package real
    
    import (
        "net/http"
        "net/http/httputil"
        "time"
    )
    
    type Retriever struct {
    
        // 数据
        UserAgent string
    
        // 超时时间
        TimeOut time.Duration
    
    }
    
    // 这里指定了是指针,在外面就只能用指针开接收
    // 不建议使用接口指针,因为本身就自带了指针
    func (r Retriever) Get(url string) string {
    
        resp, err := http.Get(url)
        if err != nil {
            // 抛出一个错误
            panic(err)
        }
    
        // 第一个参数,把返回来的resp放入,第二个参数,是否返回body体,为true
        result, err := httputil.DumpResponse(resp, true)
        // 关闭请求
        resp.Body.Close()
    
        if err != nil {
            panic(err)
        }
    
        // 因为返回的是byte切片,所以需要转换为string
        return string(result)
    }
    
    
    
    

    main方法

     package main
    
    import (
        "fmt"
        "interfaces/mock"
        "interfaces/real"
        "time"
    )
    
    /**
        Go语言规定,只要实现了接口里面的方法,就是该接口的实现类
    
        接口变量里面有什么?
        实现者的类型 和 实现者的指针
    
        接口变量自带指针
        接口变量同样采用值传递,几乎不需要使用接口的指针
        指针接收者实现只能以指针方式使用;值接收者都可以用
    
     */
    
    // 声明一个接口类型
    type Retriever interface {
        // Get方法
        // 一个未实现的方法
        Get(url string) string
    }
    
    func download(r Retriever) string {
        return r.Get("http://www.imooc.com")
    }
    
    func main() {
        // 声明接口类型,但不分配内存
        var r Retriever
        // 获取 一个实现类,并赋值给 r
        // 因为 mock.Retriever 实现了 Retriever 接口里的方法,所以他就是一个实现类
        // 这里相当于就是把 mock.Retriever 值复制了一份,然后赋值给 r
        r = mock.Retriever{"这是一个百度网页"}
    
        // 输出是什么类型,也就是实现类型,以及值
        fmt.Printf("%T %v\n",r ,r)
    
        // 什么接口类型, 但不分配内存
        var rb Retriever
        // 实现类
        // 不建议使用接口指针,因为本身就自带了指针, 可以直接用指针
        rb = &real.Retriever{
            UserAgent: "Mozilla/5.0",
            TimeOut: time.Minute,
        }
    
        // 输出是什么类型,也就是实现类型,以及值
        fmt.Printf("%T %v\n",rb ,rb)
    
        //fmt.Println(download(r))
        //fmt.Println(download(rb))
    
        // 判断是什么类型
        inspect(rb)
    
        // 类型断言
        // 如果是指针就要用指针, 普通的就直接用,比如:mock.Retriever
        realRetriever, ok := r.(*real.Retriever)
        if ok {
            fmt.Println(realRetriever.TimeOut)
        } else {
            fmt.Println("这不是 mock.Retriever 类型")
        }
    
    
    }
    
    // 判断是什么类型
    func inspect(r Retriever)  {
    
        // 判断是什么样的类型
        switch v := r.(type) {
        case mock.Retriever:
            fmt.Println("Contents: ", v.Contents)
        case *real.Retriever:
            fmt.Println("UserAgent: ", v.UserAgent)
    
        }
    }
    
    
    

    相关文章

      网友评论

          本文标题:golang-接口

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