接口
type Traversal interface {
Traverse()
}
func main() {
traversal := getTraversal()
traversal .Traverse()
}
接口的概念
- 强类型语言:熟悉接口概念
- 弱类型语言:没(少)有接口的概念
- 接口的详细:使用Google Guice实现依赖注入
duck tying
大黄鸭是鸭子吗?
- “像鸭子走路,像鸭子叫(长的像鸭子),那么就是鸭子”
- 描述事物的外部行为而非内部结构
- 严格说go属于结构化系统类型,类似duck typing
- 运行时才知道传入的retriever有没有get
- 编写download接口时需要注释来说明retriever需要实现get接口
- 编译时才知道传入的retriever有没有get方法
- 需要注释来说明接口
- 传入的参数必须实现Retriever接口
- 不是duck typing
接口的定义和实现
- 接口定义
type Retriever interface {
Get(source string) string
}
func download(retriever Retriever) string {
return retriever.Get("www.imooc.com")
}
- 接口由使用者定义
接口的实现
- 接口的实现时隐式的
- 只要实现接口里的方法
接口变量里面由什么
- 接口变量自带指针
- 接口变量同样采用值传递,几乎不需要使用接口的指针
- 指针接收者实现只能以指针方式使用;值接收者都可
查看接口类型
- 表示任何类型:interface{}
//Queue里面可以存放任何类型的数据
type Queue [] interface{}
func (q *Queue) Pop() int {
head := (*q)[0]
*q = (*q)[1:]
return head.(int) //类型转化
}
- Type Assertion
//Type assertion .(...)获取括号类型里的具体类型
if realRetriever, ok := r.(*rreal_.Retriever); ok {
fmt.Println(realRetriever.TimeOut)
} else {
fmt.Println("not a mock retriever")
}
- Type switch
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 *rreal_.Retriever:
fmt.Println("UserAgent:", v.UserAgent)
}
}
接口的组合
/*%T %v*/
type Retriever interface {
Get(url string) string
}
type Poster interface {
Post(url string, form map[string]string) string
}
//接口组合
type RetrieverPost interface {
Retriever
Poster
}
常用的系统接口
- stringer
- Reader
- Writer