Golang学习笔记(4)面向接口
程序员文章站
2022-04-27 08:16:46
...
第四章 面向接口
接口的定义
- 接口由使用者定义
type Retiever interface {
Get( url string ) string
}
func download( retriever Retiever ) {
return retriever.Get("http://www.baidu.com")
}
- 接口的实现是隐式的
- 只要实现接口里的方法
接口变量里有什么
func main() {
var r Retriever
}
// mock.go
package mock
type Retriever struct {
Contents string
}
func (r *Retriever) Get(url string) string {
return r.Contents
}
// real.go
package real
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)
}
- 实现者的类型 和 实现者的指针
- 接口变量自带指针
- 接口变量才用值传递, 几乎不需要使用接口的指针
查看接口变量
- 表示任何类型:interface{}
- Type Assertion
var r Retriever
if mockRetriever, ok := r.(*mock.Retriever); ok {
fmt.Println(mockRetriever.Contents)
} else {
fmt.Println("r is not a mock retriever")
}
- Type Switch
func inspect(r Retriever) {
fmt.Println("Inspecting", r)
fmt.Printf(" > Type:%T Value:%v\n", r, r)
fmt.Print(" > Type switch: ")
switch v := r.(type) {
case *mock.Retriever:
fmt.Println("Contents:", v.Contents)
case *real.Retriever:
fmt.Println("UserAgent:", v.UserAgent)
}
fmt.Println()
}
var r Retriever
mockRetriever := mock.Retriever{Contents: "this is a fake imooc.com"}
r = &mockRetriever
inspect(r)
r = &real.Retriever{
UserAgent: "Mozilla/5.0",
TimeOut: time.Minute,
}
inspect(r)
接口的组合
type Poster interface {
Post(url string,
form map[string]string) string
}
const url = "http://www.imooc.com"
func post(poster Poster) {
poster.Post(url,
map[string]string{
"name": "ccmouse",
"course": "golang",
})
}
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)
}