main.go:(使用者)
package main
import "fmt"
type Retriever interface {
Get(url string) string
}
type Poster interface {
Post(url string, form map[string]string) string
}
const url = "http://www.imooc.com"
func download(r Retriever) string {
return r.Get(url)
}
func post(poster Poster) {
poster.Post(url,
map[string]string {
"name": "ccmouse",
"course": "golang",
})
}
// 接口的组合:组合Retriever接口和Poster接口
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
retriever := mock.Retriever{"this is a fake imooc.com"}
r = &retriever
inspect(r)
r = &real.Retriever{
UserAgent: "Mozilla/5.0",
TimeOut: time.Minute,
}
inspect(r)
// Type assertion
if mockRetriever, ok := r.(*mock.Retrivever); ok {
fmt.Println(mockRetriever.Contents)
} else {
fmt.Println("not a mock retriever")
}
fmt.Println("Try a session")
fmt.Println(session(&retriever)) // another faked imooc.com
}
func inspect(r Retriever) {
switch v := r.(type) {
case *mock.Retriever:
fmt.Println("Contents:", v.Contents)
case *real.Retriever:
fmt.Println("UserAgent:", v.UserAgent)
}
}
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)
}