duck typing
1、 接口组装
2、 类型检查
使用--> 实现者
接口由使用者定义
接口实现是隐式的,只要实现接口里的方法
接口变量:包括实现者的值,实现者的类型 ; 实现者的值也可以是实现者指针
接口变量自带指针
接口变量同样采用值传递,几乎不需要使用接口的指针
指针接收者实现只能以指针方式使用,值接收者都可以
查看接口变量
表示任何类型: insterface{}
Type Assertion
Type Switch
// 指定int 类型
type Queue []int
func (q *Queue) Push(v int) {
*q = append(*q,v)
}
func (q *Queue) Pop() int {
head :=(*q)[0]
*q = (*q)[1:]
return head
}
func (q *Queue) IsEmpty() bool {
return len(*q) == 0
}
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
}
func (q *Queue) IsEmpty() bool {
return len(*q) == 0
}
查看接口
var r Retriever
r = mock.Retriever{"this is my test interface"}
fmt.Printf("%T %v" ,r,r )
输入结果:
mock.Retriever {this is my test interface}
type switch
func inspect( r Retriever) {
fmt.Printf("%T %v" ,r,r )
switch v := r.(type) {
case mock.Retriever:
fmt.Println("Contents:",v.Contents)
case *real.Retriever:
fmt.Println("UserAgent:",v.UserAgent)
}
}
type assertion
r = &real.Retriever{
UserAgent: "Mozilla/5.0",
TimeOut: time.Minute,
}
// type assertion
// r 类型已指定 &real.Retriever ,再使用 r.()进行转换,会提示报错
if retriever, ok:= r.(mock.Retriever) ; ok {
fmt.Println( retriever.Contents)
}else {
fmt.Println(" not a mock Retriever")
}
接口组合
定义接口:
type Retriever interface {
Get(url string) string
}
type Poster interface {
Post(url string ,form map[string]string) string
}
组合接口:
type RetrieverPoster interface {
Retriever
Poster
}
实现者接口:
type Retriever struct{
Contents string
}
func (r Retriever) Post(url string, form map[string]string) string {
r.Contents = form["contents"]
return "ok"
}
func (r Retriever) Get(url string) string {
return r.Contents
}
实现者接口:
type Retriever struct {
UserAgent string
TimeOut time.Duration
}
func (r *Retriever) Post(url string, form map[string]string) string {
r.UserAgent = form["contents"]
return "ok"
}
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)
}
测试:
retriever := mock.Retriever{"this is default value"}
fmt.Println(session(retriever))
realretriever := &real.Retriever{UserAgent: "this is default Value"}
fmt.Println(session(realretriever))
fmt.Println(realretriever.UserAgent)