main.go:(使用者)

    1. package main
    2. import "fmt"
    3. type Retriever interface {
    4. Get(url string) string
    5. }
    6. type Poster interface {
    7. Post(url string, form map[string]string) string
    8. }
    9. const url = "http://www.imooc.com"
    10. func download(r Retriever) string {
    11. return r.Get(url)
    12. }
    13. func post(poster Poster) {
    14. poster.Post(url,
    15. map[string]string {
    16. "name": "ccmouse",
    17. "course": "golang",
    18. })
    19. }
    20. // 接口的组合:组合Retriever接口和Poster接口
    21. type RetrieverPoster interface {
    22. Retriever
    23. Poster
    24. }
    25. func session(s RetrieverPoster) string {
    26. s.Post(url, map[string]string {
    27. "contents": "another faked imooc.com",
    28. })
    29. return s.Get(url)
    30. }
    31. func main() {
    32. var r Retriever
    33. retriever := mock.Retriever{"this is a fake imooc.com"}
    34. r = &retriever
    35. inspect(r)
    36. r = &real.Retriever{
    37. UserAgent: "Mozilla/5.0",
    38. TimeOut: time.Minute,
    39. }
    40. inspect(r)
    41. // Type assertion
    42. if mockRetriever, ok := r.(*mock.Retrivever); ok {
    43. fmt.Println(mockRetriever.Contents)
    44. } else {
    45. fmt.Println("not a mock retriever")
    46. }
    47. fmt.Println("Try a session")
    48. fmt.Println(session(&retriever)) // another faked imooc.com
    49. }
    50. func inspect(r Retriever) {
    51. switch v := r.(type) {
    52. case *mock.Retriever:
    53. fmt.Println("Contents:", v.Contents)
    54. case *real.Retriever:
    55. fmt.Println("UserAgent:", v.UserAgent)
    56. }
    57. }

    mockretriever.go:(实现者)

    package mock
    
    type Retriever struct {
        Contents string
    }
    
    // 只要实现了Post方法和Get方法,就实现了RetrieverPoster接口
    func (r *Retriever) Post(url string, form map[string]string) string {
        r.Contents = form["contents"]
        return "ok"
    }
    
    func (r *Retriever) Get(url string) string {
        return r.Contents
    }
    

    retriever.go:(实现者)

    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)
        }
    
        result, err := httputil.DumpResponse(
            resp, true)
    
        resp.Body.Close()
    
        if err != nil {
            panic(err)
        }
    
        return string(result)
    }