go语言是一门面向接口的语言
duck typing
这个大黄鸭是鸭子吗?
- 传统类型系统:脊索动物门、脊椎动物亚门、鸟纲雁形目。。。
从传统类型系统来看,这个大黄鸭不是鸭子,从duck typing来看,这个大黄鸭是鸭子“像鸭子走路、像鸭子叫,这就是鸭子”
描述事物的外部行为而非内部结构
严格说go属于结构化类型系统,类似duck typing
Python中的duck typing
def download(retriever):
return retriever.get("www.baidu.com")
接口的定义
上面python的示例中download(使用者)——》retriever(实现者)
go语言中的接口是由使用者来定义的
import "fmt"
type Retriever interface {
Get(url string) string
}
func download(r Retriever) string {
return r.Get("www.baidu.com")
}
func main() {
var r Retriever
fmt.Println(download(r))
}
运行结果如下:
因为var r还没有定义,不知道是什么东西,所以报错。以下实现一个retriever
mock.go
package mock
type Retriever struct {
Contents string
}
func (r Retriever) Get(url string) string {
return r.Contents
}
main.go
package main
import (
"StudyGo/retriever/mock"
"fmt"
)
type Retriever interface {
Get(url string) string
}
func download(r Retriever) string {
return r.Get("www.baidu.com")
}
func main() {
var r Retriever
r = mock.Retriever{"this is a fake baidu.com"}
fmt.Println(download(r))
}
运行结果如下:
在比如一个爬虫的例子:
retriever.go
package real2
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)
}
response, err := httputil.DumpResponse(resp, true)
resp.Body.Close()
if err != nil{
panic(err)
}
return string(response)
}
main.go
package main
import (
"StudyGo/retriever/mock"
real2 "StudyGo/retriever/real"
"fmt"
)
type Retriever interface {
Get(url string) string
}
func download(r Retriever) string {
return r.Get("http://www.baidu.com")
}
func main() {
var r Retriever
r = mock.Retriever{"this is a fake baidu.com"}
r = real2.Retriever{}
fmt.Println(download(r))
}
运行结果如下: