go结构化类型系统,类似与duck typing go语言是编译时就会绑定的,从动态绑定的角度,不是duck typing
具有c++、python的灵活性,实现对应的方法就可以运行,又想要java的类型检查
go的接口实现是隐式的,只要实现接口里的方法就可以
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 package mocktype Retriever1 struct { Contents string } func (r Retriever1) Get (str string ) string { return r.Contents } package real import ( "net/http" "net/http/httputil" "time" ) type Retriever2 struct { UserAgent string TimeOut time.Duration } func (r *Retriever2) 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 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 package mainimport ( "fmt" "type_interface/mock" real2 "type_interface/real" ) type Retriever3 interface { Get(url string ) string } func download (r Retriever3) string { return r.Get("http://www.baidu.com" ) } func inspect (r Retriever3) { switch v := r.(type ) { case mock.Retriever1: fmt.Println("mock.Retriever1: " , v.Contents) case *real2.Retriever2: fmt.Println("*real2.Retriever2: " , v.UserAgent) } } func main () { var r Retriever3 r = mock.Retriever1{Contents: "this is faker, you know?" } inspect(r) r = &real2.Retriever2{ UserAgent: "chrome 19.0" , TimeOut: time.Minute, } inspect(r) realRetriever := r.(*real2.Retriever2) fmt.Println(realRetriever.TimeOut) if mockRetriever, ok := r.(mock.Retriever1); ok { fmt.Println(mockRetriever.Contents) } else { fmt.Printf("r is not a mockRetriever" ) } }
查看接口变量
表示任何变量: interface{}
Type Assertion
Type Switch
接口的组合 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 package mocktype Retriever1 struct { Contents string } func (r *Retriever1) String () string { return fmt.Sprintf("实现的string方法返回的内容是 Retriever1: {Contents=%s} " , r.Contents) } func (r *Retriever1) Post (url string , form map [string ]string ) string { r.Contents = form["contents" ] return "ok" } func (r *Retriever1) Get (str string ) string { return r.Contents } type Retriever3 interface { Get(url string ) string } type Poster interface { Post(url string , form map [string ]string ) string } type RetrieverPoster interface { Retriever3 Poster } func session (s RetrieverPoster) string { s.Post(url, map [string ]string { "name" : "edit" , "contents" : "faker is here right" , }) return s.Get(url) } func printFlie (filename string ) { file, err := os.Open(filename) if err != nil { panic (err) } scanner := bufio.NewScanner(file) for scanner.Scan() { fmt.Println(scanner.Text()) } } func main () { var r Retriever3 r = &mock.Retriever1{Contents: "this is faker, you know?" } fmt.Printf(session(r.(*mock.Retriever1))) fmt.Println(r) }