5-4 接口的组合

main.go

package main

import (
    "fmt"
    "retriever/mock"
    "retriever/real"
    "time"
)

const url = "http://www.imooc.com"
// 下载接口
type Retriever interface {
    Get(url string) string
}

func download(r Retriever) string {
    return r.Get(url)
}

// 上传接口
type Poster interface {
    Post(utl string, form map[string]string) string
}

func post(poster Poster) {
    poster.Post(url,
        map[string]string {
            "name": "ccmouse",
            "course": "golang",
        })
}

// 可以有多个小接口组合
type RetrieverPoster interface {
    Retriever
    Poster
}
func session(s RetrieverPoster) string {
    s.Post(url, map[string]string {
        "contents": "another faked imooc.com",
    })
    return s.Get(url)
}

func main() {
    var r Retriever
    // mock/mockretriever.go
    // mock.Retriever现在是RetrieverPoster接口
    fmt.Println("-----------测试mock.Retriever接口----------------")
    r = &mock.Retriever{Contents:"this is a fake imooc.com"}
    inspect(r)
    // fmt.Println(download(r))
    //Type assertion
    mockRetriever := r.(*mock.Retriever)
    fmt.Println("Type assertion: "+mockRetriever.Contents)

    fmt.Println("\n------------测试real.RealRetriever接口---------------")

    // real/retriever.go
    r = &real.RealRetriever{
        UserAgent: "Mozilla/5.0",
        TimeOut: time.Minute,
    }
    inspect(r)
    // fmt.Println(download(r))
    //Type assertion
    realRetriever := r.(*real.RealRetriever)
    fmt.Println("Type assertion: "+realRetriever.UserAgent)
    //  判断接口的类型
    if mockRetriever,ok := r.(*mock.Retriever); ok {
        fmt.Println("Type assertion: "+mockRetriever.Contents)
    } else {
        fmt.Println("not mock a retriever")
    }
    fmt.Println("\n----------测试RetrieverPoster接口-----------------")
    fmt.Println(session(mockRetriever))
}

// 如何判断接口的类型
func inspect(r Retriever) {
    // %T查看类型 %v查看数值
    fmt.Printf("类型:%T 数值:%v\n", r, r)
    fmt.Println("Type switch")
    switch v := r.(type) {
    case *mock.Retriever:
        fmt.Println("Contents: "+v.Contents)
    case *real.RealRetriever:
        fmt.Println("UserAgent: "+v.UserAgent)
    }
    //mock.Retriever {this is a fake imooc.com}
    //Contents: this is a fake imooc.com
    //*real.RealRetriever &{Mozilla/5.0 1m0s}
    //UserAgent: Mozilla/5.0
}

mock/mockretriever.go

package mock

// mock.Retriever现在是RetrieverPoster接口
type Retriever struct {
    Contents string
}

//func (r *Retriever)Get(url string) string {
func (r Retriever)Get(url string) string {
    return r.Contents
}

// 这里需要是r *Retriever,否则原对象的r.Contents数值不会改变
func (r *Retriever)Post(url string,
    form map[string]string) string {
    r.Contents = form["contents"]
    return "ok"
}

real/retriever.go

package real

import (
    "time"
    "net/http"
    "net/http/httputil"
)

type RealRetriever struct {
    UserAgent string
    TimeOut time.Duration
}

func (r *RealRetriever) Get(url string) string {
    resp, err := http.Get(url)
    if err != nil {
        panic(err)
    }
    result, err := httputil.DumpResponse(
        resp, true)
    resp.Body.Close()
    if err != nil {
        panic(err)
    }
    return string(result)
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值