formatLoopformatLoopformatLoop#### 接口的概念 main.go
package main import ( "ZipTest_backend/infra" "ZipTest_backend/testing" "fmt" ) // func traverse(url string) []byte { // resp, err := http.Get(url) // if err != nil { // panic(err) // } // defer resp.Body.Close() // bytes, _ := ioutil.ReadAll(resp.Body) // return bytes // } func getRetriever() infra.RetrieverBody { return infra.RetrieverBody{} } func getRetrieverTest() testing.Retriever { return testing.Retriever{} } func main() { // // traverse := infra.Retriever{} // var traverse infra.Retriever = getRetriever() // fmt.Println(string(traverse.Get("https://www.imooc.com"))) // var traverseTest testing.Retriever = getRetrieverTest() // fmt.Println(string(traverseTest.Get("https://www.imooc.com"))) var trieverInterface = infra.Retriever() fmt.Println(trieverInterface.Get("https://www.imooc.com")) }infra/infra.go
package infra import ( "io/ioutil" "net/http" ) type RetrieverInterface interface { Get(string) string } type RetrieverBody struct{} // func () func Retriever() RetrieverInterface { return RetrieverBody{} } func (RetrieverBody) Get(url string) string { resp, err := http.Get(url) if err != nil { panic(err) } defer resp.Body.Close() bytes, _ := ioutil.ReadAll(resp.Body) return string(bytes) }testing/retriever.go
package testing type Retriever struct{} func (Retriever) Get(url string) string { return "fake content" } 强类型语言:熟悉接口的概念弱类型语言:没有(少)接口的概念curl命令是linux\mac系统上请求http链接的命令,会将整个网页的源码打印出来模块化main.go
package main import ( "ZipTest_backend/mock" "ZipTest_backend/real" "fmt" ) type Retriever interface { Get(string) string } func download(r Retriever) string { return r.Get("http://www.imooc.com") } func main() { var r Retriever r = mock.Retriever{"this is a fake imooc.com"} fmt.Println(download(r)) var realR Retriever = real.Retriever{} fmt.Println(download(realR)) }real/real.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) }mock/mockretriever.go
package mock type Retriever struct { Contents string } func (r Retriever) Get(url string) string { return r.Contents }main.go
package main import ( "ZipTest_backend/mock" "ZipTest_backend/real" "fmt" "time" ) type Retriever interface { Get(string) string } func download(r Retriever) string { return r.Get("http://www.imooc.com") } func inspect(r Retriever) { 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.Retriever: fmt.Println("UserAgent : ", v.UserAgent) } } func main() { var r Retriever r = mock.Retriever{"this is a fake imooc.com"} inspect(r) // fmt.Println(download(r)) var realR Retriever = &real.Retriever{ UserAgent: "Mozilla/5.0", TimeOut: time.Minute, } // fmt.Printf("%T %v\n", realR, realR) inspect(realR) realRetriever := realR.(*real.Retriever) fmt.Println(realRetriever.TimeOut) if mockRetriever, ok := realR.(mock.Retriever); ok { fmt.Println(mockRetriever.Contents) } else { fmt.Println("not a mock retriever") } // fmt.Println(download(realR)) } 接口变量自带指针接口变量同样采用值传递,几乎不需要使用接口的指针指针接受者实现只能以指针方式使用;值接受者都可便是任何类型:interface{}Type AssertionType Switch