一.接口的概念
1.强类型语言:熟悉接口的概念 java c++
2.弱类型语言:没有(少)接口的概念 php
// 上代码,详解接口的概念:
func getRetriever() retriever {
return testing.Retriever{}
}
type retriever interface {
Get(string) string
}
func main() {
// 这边定义的retriever,我们并不知道他是属于infra,还是testing的Retriever
var r retriever = getRetriever()
fmt.Printf(r.Get(("https://www.imooc.com")))
}
// 如果没有接口的写法
func getRetriever() infra.retriever {
return infra.Retriever{}
}
func main() {
// 这边的retriever很明确就是infra包的Retriever
var retriever infra.Retriever = getRetriever()
fmt.Printf(retriever.Get(("https://www.imooc.com")))
}
二.Dark typing
1."像鸭子走路,像鸭子",那么就是鸭子
2.描述事物的外部行为而非内部结构
3.严格说go属于结构化类型系统,类似duck typing
三.接口的定义和实现
接口的定义和实现:
- 接口由使用者定义
- 接口的实现是隐式的
- 接口只要实现里面的方法
type Retriever interface {
Get(url string) string
}
func download(r Retriever) string {
return r.Get("https://www.imooc.com")
}
四. 接口的值类型
接口变量里面有什么东西?
1.实现者的类型
2.实现者的值(实现者的指针)
3.指针接收者实现只能以指针方式实现,值接收者都可以
如何查看接口变量?
1.interface{}
type Queue []interface{}
func (q *Queue) Push(v interface{}) {
*q = append(*q, v)
}
func (q *Queue) Pop() interface{} {
head := (*q)[0]
*q = (*q)[1:]
return head
}
2.type assertion
// 方式二Type assertion
realRetriever := r.(*real2.Retriever)
fmt.Println(realRetriever.TimeOut)
3.type switch
func inspect(r Retriever) {
fmt.Printf("%T %v\n", r, r)
switch v := r.(type) {
case *real2.Retriever:
fmt.Println("userAgent:" + v.UserAgent)
case mock.Retriever:
fmt.Println("Contents:" + v.Contents)
}
}
五.接口的组合
type Retriever interface {
Get(url string) string
}
type Poseter interface {
Post(url string, form map[string]string) string
}
type RetrieverPoster interface {
Retriever
Poseter
}
func session(s RetrieverPoster) string {
s.Post(URL, map[string]string{
"contents": "session's contents",
})
return s.Get(URL)
}