1 package main 2 3 import ( 4 "awesomeProject/retriever/mock" 5 "awesomeProject/retriever/real" 6 "fmt" 7 "time" 8 ) 9 10 //接口由使用者定义 11 //接口的实现是隐式的,只要实现接口里的方法 12 //接口变量自带指针 13 //接口变量采用值传递,几乎不需要使用接口的指针 14 //指针接收者实现只能以指针方式使用,值接收者都可 15 //查看接口变量: 16 // 表示任何类型 :interface{} 17 // Type Assertion 18 // Type Switch 19 20 type Retriever interface { 21 Get( url string) string 22 } 23 24 type Postser interface { 25 Post(url string, 26 form map[string] string) string 27 } 28 29 const url = "http://www.baidu.com" 30 func post( postser Postser) { 31 postser.Post(url, map[string] string{ 32 "name": "yuxiaoba", 33 "course": "go", 34 }) 35 } 36 37 type RetrieverPoster interface { //接口的组合 38 Retriever 39 Postser 40 } 41 42 func session( s RetrieverPoster) string{ 43 44 s.Post(url, map[string]string{ 45 "contents": "another faked baidu.com", 46 }) 47 return s.Get(url) 48 } 49 //func download( r Retriever) string { 50 // return r.Get("http://www.baidu.com") 51 //} 52 53 func inspect(r Retriever) { 54 switch v := r.(type) { 55 case *mock.Retriever: 56 fmt.Println("Contents", v.Contents) 57 58 case *real.Retriever: 59 fmt.Println("UserAgent", v.UserAgent) 60 } 61 fmt.Printf("%T %v ", r, r) 62 fmt.Println() 63 } 64 65 func main() { 66 var r Retriever 67 retriever := mock.Retriever{"this is a fake baidu"} 68 r = &retriever 69 inspect(r) //Contents this is a fake baidu 70 // *mock.Retriever Retriver: {Contents = this is a fake baidu} 71 72 r = &real.Retriever{ 73 UserAgent: "Mozilla/5.0", 74 TimeOut: time.Minute, 75 } 76 inspect(r) //UserAgent Mozilla/5.0 77 /* *real.Retriever &{Mozilla/5.0 1m0s}*/ 78 79 //type assertion 80 realRetriever := r.(*real.Retriever) 81 82 if mockRetriever , ok := r.(*mock.Retriever); ok { 83 fmt.Println(mockRetriever.Contents) 84 }else { 85 fmt.Println("not mock retriever") //not mock retriever 86 } 87 88 fmt.Println(realRetriever.TimeOut) //1m0s 89 /* fmt.Println(download(r))*/ 90 91 fmt.Println(session(&retriever)) //another faked baidu.com 92 93 }
package real import ( "time" "net/http" "net/http/httputil" ) //真实retriever 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) }
1 package mock 2 3 import "fmt" 4 5 type Retriever struct { 6 Contents string 7 } 8 9 func (r *Retriever) String() string { 10 return fmt.Sprintf( 11 "Retriver: {Contents = %s}", r.Contents, 12 ) 13 } 14 15 func (r *Retriever) Post (url string, 16 form map[string]string) string { 17 r.Contents = form["contents"] 18 return "OK" 19 } 20 21 func (r *Retriever) Get(url string) string { 22 return r.Contents 23 }