Go语言规定,只要实现了接口里面的方法,就是该接口的实现类
接口变量里面有什么?
实现者的类型 和 实现者的指针
接口变量自带指针
接口变量同样采用值传递,几乎不需要使用接口的指针
指针接收者实现只能以指针方式使用;值接收者都可以用
定义一个接口
package main
import (
"fmt"
"interfaces/mock"
"interfaces/real"
"time"
)
/**
Go语言规定,只要实现了接口里面的方法,就是该接口的实现类
接口变量里面有什么?
实现者的类型 和 实现者的指针
接口变量自带指针
接口变量同样采用值传递,几乎不需要使用接口的指针
指针接收者实现只能以指针方式使用;值接收者都可以用
。。。。
type Retriever struct {}
type Retriever string
等等,都可以算是这个 Retriever 接口的实现类
。。。。
*/
// 声明一个接口类型
type Retriever interface {
// Get方法
// 一个未实现的方法
Get(url string) string
}
func download(r Retriever) string {
return r.Get("http://www.imooc.com")
}
func main() {
// 声明接口类型,但不分配内存
var r Retriever
// 获取 一个实现类,并赋值给 r
// 因为 mock.Retriever 实现了 Retriever 接口里的方法,所以他就是一个实现类
// 这里相当于就是把 mock.Retriever 值复制了一份,然后赋值给 r
r = mock.Retriever{"这是一个百度网页"}
// 输出是什么类型,也就是实现类型,以及值
fmt.Printf("%T %v\n",r ,r)
// 什么接口类型, 但不分配内存
var rb Retriever
// 实现类
// 不建议使用接口指针,因为本身就自带了指针, 可以直接用指针
rb = &real.Retriever{
UserAgent: "Mozilla/5.0",
TimeOut: time.Minute,
}
// 输出是什么类型,也就是实现类型,以及值
fmt.Printf("%T %v\n",rb ,rb)
//fmt.Println(download(r))
//fmt.Println(download(rb))
// 判断是什么类型
inspect(rb)
// 类型断言
// 如果是指针就要用指针, 普通的就直接用,比如:mock.Retriever
realRetriever, ok := r.(*real.Retriever)
if ok {
fmt.Println(realRetriever.TimeOut)
} else {
fmt.Println("这不是 mock.Retriever 类型")
}
}
// 判断是什么类型
func inspect(r Retriever) {
// 判断是什么样的类型
switch v := r.(type) {
case mock.Retriever:
fmt.Println("Contents: ", v.Contents)
case *real.Retriever:
fmt.Println("UserAgent: ", v.UserAgent)
}
}
接口实现1
package mock
/**
这里是一个实现类,结构名称最好和那个接口名称一样
然后在实现那个接口里面的 Get 方法
Go语言规定,只要实现了接口里面的方法,就是该接口的实现类
*/
type Retriever struct {
// 结构体里面的属性
Contents string
}
// 实现接口 Retriever 里面的方法 Get
func (r Retriever) Get(url string) string {
// 实现的方法体
return r.Contents
}
接口实现 2
package real
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)
}
// 第一个参数,把返回来的resp放入,第二个参数,是否返回body体,为true
result, err := httputil.DumpResponse(resp, true)
// 关闭请求
resp.Body.Close()
if err != nil {
panic(err)
}
// 因为返回的是byte切片,所以需要转换为string
return string(result)
}
main方法
package main
import (
"fmt"
"interfaces/mock"
"interfaces/real"
"time"
)
/**
Go语言规定,只要实现了接口里面的方法,就是该接口的实现类
接口变量里面有什么?
实现者的类型 和 实现者的指针
接口变量自带指针
接口变量同样采用值传递,几乎不需要使用接口的指针
指针接收者实现只能以指针方式使用;值接收者都可以用
*/
// 声明一个接口类型
type Retriever interface {
// Get方法
// 一个未实现的方法
Get(url string) string
}
func download(r Retriever) string {
return r.Get("http://www.imooc.com")
}
func main() {
// 声明接口类型,但不分配内存
var r Retriever
// 获取 一个实现类,并赋值给 r
// 因为 mock.Retriever 实现了 Retriever 接口里的方法,所以他就是一个实现类
// 这里相当于就是把 mock.Retriever 值复制了一份,然后赋值给 r
r = mock.Retriever{"这是一个百度网页"}
// 输出是什么类型,也就是实现类型,以及值
fmt.Printf("%T %v\n",r ,r)
// 什么接口类型, 但不分配内存
var rb Retriever
// 实现类
// 不建议使用接口指针,因为本身就自带了指针, 可以直接用指针
rb = &real.Retriever{
UserAgent: "Mozilla/5.0",
TimeOut: time.Minute,
}
// 输出是什么类型,也就是实现类型,以及值
fmt.Printf("%T %v\n",rb ,rb)
//fmt.Println(download(r))
//fmt.Println(download(rb))
// 判断是什么类型
inspect(rb)
// 类型断言
// 如果是指针就要用指针, 普通的就直接用,比如:mock.Retriever
realRetriever, ok := r.(*real.Retriever)
if ok {
fmt.Println(realRetriever.TimeOut)
} else {
fmt.Println("这不是 mock.Retriever 类型")
}
}
// 判断是什么类型
func inspect(r Retriever) {
// 判断是什么样的类型
switch v := r.(type) {
case mock.Retriever:
fmt.Println("Contents: ", v.Contents)
case *real.Retriever:
fmt.Println("UserAgent: ", v.UserAgent)
}
}
有疑问加站长微信联系(非本文作者)