golang学习笔记——面向接口

tech2024-11-22  16

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链接的命令,会将整个网页的源码打印出来模块化

duck typing的概念

“像鸭子走路,像鸭子叫(长得像鸭子),那么就是鸭子”描述事务的外部行为而非内部结构严格说go属于结构化类型系统,类似duck typingpython——运行时才知道传入的retriever有没有getpython——需要注释来说明接口C++——编译时才知道传入的retriever有没有getC++——需要注释来说明接口JAVA没有duck typingJAVA有类似的代码JAVA——传入的参数必须实现retriever的接口GO——同时需要Readable、AppendableGO——同时具有python,c++的duck typing的灵活性GO——又具有java的类型检查

接口的定义和实现

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
最新回复(0)