interface{} 表示可以接纳所有的类型
未使用 interface{} 类型
package queue
// 声明一个类型 Queue 类型,这个类型是用 []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
}
// 判断是否有值, 是否为empty
func (q *Queue) IsEmpty() bool {
return len(*q) == 0
}
使用了 interface{} 类型,用例1
package queue
// 声明一个类型 Queue2 类型,这个类型是用 []interface {} 切片实现的,这个切片类型是interface{}
/**
用 interface{} 表示,可以接收任何类型
*/
type Queue2 []interface {}
// 添加元素, 表示可以添加任何类型的元素
func (q *Queue2) Push(v interface{}) {
// 这里使用指针,才可以把数据真正的添加进去,共外部可用
*q = append(*q, v)
}
// 弹出顶层元素
func (q *Queue2) Pop() interface{} {
// 获取最顶层元素
head := (*q)[0]
// 把顶层元素剔除
*q = (*q)[1:]
return head
}
// 判断是否有值, 是否为empty
func (q *Queue2) IsEmpty() bool {
return len(*q) == 0
}
使用了interface{} 类型。用例2
package queue
// 声明一个类型 Queue2 类型,这个类型是用 []interface {} 切片实现的,这个切片类型是interface{}
/**
用 interface{} 表示,可以接收任何类型
*/
type Queue3 []interface {}
// 添加元素, 我这里限定只能添加 int 类型元素
func (q *Queue3) Push(v int) {
// 这里使用指针,才可以把数据真正的添加进去,共外部可用
*q = append(*q, v)
}
// 弹出顶层元素
// 我这里是用 Queue3 是 interface{} 类型,什么元素都可以添加
// 但是我现在只希望返回的类型是 int
func (q *Queue3) Pop() int {
// 获取最顶层元素
head := (*q)[0]
// 把顶层元素剔除
*q = (*q)[1:]
// 把值转换为 int
return head.(int)
}
// 判断是否有值, 是否为empty
func (q *Queue3) IsEmpty() bool {
return len(*q) == 0
}
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)
}
}
有疑问加站长微信联系(非本文作者)