Go接口

43 阅读3分钟

接口 Interface

Interface 是是一个编程规约,也是一组Method签名的组合,可以通过Interface来定义对象的一组行为。如果某个对象实现了某个接口的所有方法,就表示它实现了该“接口”。

接口的声明

 type 接口名 interface{
     方法名(参数列表)(返回值)
     方法名(参数列表)(返回值)
     ...
 }

注意:

1、Go语言中,Interface命名时习惯以“er”结尾。

2、Go语言中,一个Interface中包含的Method不宜过多,一般0~3个

3、一个Interface可以被多个对象实现,一个对象也可以实现多个Interface。

实例:

 package main
 ​
 import "fmt"
 ​
 //声明一个接口
 type Usber interface {
     //声明了两个没有实现的方法
     Insert()
     Start()
 }
 ​
 type Phone struct{}
 ​
 type Camera struct{}
 ​
 type Computer struct{}
 ​
 //让Phone实现Usber接口的方法
 func (p Phone) Insert() {
     fmt.Printf("手机已插入...\n")
 }
 ​
 func (p Phone) Start() {
     fmt.Printf("手机开始工作...\n")
 }
 ​
 //让Camera实现Usber接口的方法
 func (c Camera) Insert() {
     fmt.Printf("相机已插入...\n")
 }
 ​
 func (c Camera) Start() {
     fmt.Printf("相机开始工作...\n")
 }
 ​
 //编写一个Working方法,接收一个Usber接口类型的变量
 //实现Usb接口(所谓实现Usber接口,就是指实现了Usber接口声明的所有方法)
 func (c Computer) Working(usb Usber) {
     usb.Insert() //这里理解为phone.Insert()或camera.Insert()
     usb.Start()  //同理
 }
 ​
 func main() {
     //测试
     //先创建结构体变量
     computer := Computer{}
     phone := Phone{}
     camera := Camera{}
 ​
     //关键点
     computer.Working(phone)
     fmt.Printf("----------------------\n")
     computer.Working(camera)
 ​
     fmt.Printf("-----------接口的赋值-----------\n")
     var p Usber //定义一个Usber类型的变量
     p = phone   //p能存储Phone
     p.Insert()
 }

运行结果:

 手机已插入...
 手机开始工作...
 ----------------------
 相机已插入...
 相机开始工作...

空接口

在Go语言中,任何数据类型都默认实现了空Interface,空接口声明:

 interface{}

空接口包含0个Method,可以使用空接口定义任何类型变参函数

一个函数把 interface{} 作为参数 / 返回值,那么它可以接受任何类型的值作为参数 / 返回值。

接口的赋值

如果定义一个Interface的变量,那么这个变量里面可以存储实现这个Interface的任意类型的对象。

     fmt.Printf("-----------接口的赋值-----------\n")
     var p Usber //定义一个Usber类型的变量
     p = phone   //p能存储Phone
     p.Insert()

接口转换

拥有超集的接口可以被转换成子集的接口,子集就可以访问超级对象中的成员变量或数据

 package main
 ​
 import "fmt"
 ​
 type People struct {
     Name string
     Age  int
 }
 ​
 type Student struct {
     People
     School string
 }
 ​
 type PeopleInfo interface {
     GetPeopleInfo()
 }
 ​
 //接口StudentInfo拥有PeopleInfo的全部方法签名
 type StudentInfo interface {
     GetPeopleInfo()
     GetStudentInfo()
 }
 ​
 func (p People) GetPeopleInfo() {
     fmt.Println(p)
 }
 ​
 func (s Student) GetStudentInfo() {
     fmt.Println(s)
 }
 ​
 func main() {
     //定义一个StudentInfo类型的变量is并赋值
     var is StudentInfo = Student{People{"tom", 18}, "sziit"}
     is.GetStudentInfo()
     is.GetPeopleInfo()
 ​
     //定义一个PeopleInfo类型的变量ip
     var ip PeopleInfo = is //PeopleInfo属于StudentInfo的一个子集,可直接将is赋值给ip
     ip.GetPeopleInfo()
 }

运行结果:

 {{tom 18} sziit}
 {tom 18}
 {tom 18}

接口类型推断

通过接口的赋值可知,接口类型变量里面可以存储任意类型的数值(该类型实现了Interface)

而反向知道接口类型变量实际保存的是哪一种类型的对象叫做接口类型推断。利用接口类型推断,可以判断接口对象是否是某个具体的接口或者类型。

1、Comma-ok 断言

 value, ok = element.(T)

value:变量的值

ok:bool类型

element:接口类型变量

T:断言的类型

如果element中确实存储了T类型的数值,那么ok返回true,否则返回false。

2、Switch 测试

 switch value := element.(type){
     case int:
     case string:
     ...
 }

注意:

element.(type) 语法不能在Switch语句外的任何逻辑语句里使用,如果要在Switch外面判断一个类型就要使用Comma-ok断言。