接口是一种类型
在Go语言中接口(interface)是一种类型,一种抽象的类型。它规定了变量有哪些方法
interface是一组method的集合,是duck-type programming的一种体现。接口做的事情就像是定义一个协议(规则),只要一台机器有洗衣服和甩干的功能,我就称它为洗衣机。不关心属性(数据),只关心行为(方法)。
在编程中会遇到以下场景:
:::warning 我不关心一个变量是什么类型,我只关心能调用它的什么方法。
:::
接口的定义
type 接口名 interface {方法名1(参数1, 参数2...)(返回值1,返回值2,...)方法名2(参数1, 参数2...)(返回值1,返回值2,...)...}
用来给变量、参数、返回值等设置类型。
实战
type speak interface {Say() string}type Cat struct{}func (c Cat) Say() string { return "喵喵喵" }type Dog struct{}func (d Dog) Say() string { return "汪汪汪" }func main() {c := Cat{}fmt.Println("猫:", c.Say())d := Dog{}fmt.Println("狗:", d.Say())}type Cat struct{}func (c Cat) Say() string { return "喵喵喵" }type Dog struct{}func (d Dog) Say() string { return "汪汪汪" }func main() {c := Cat{}fmt.Println("猫:", c.Say())d := Dog{}fmt.Println("狗:", d.Say())}
接口的实现
:::info 一个变量如果实现了接口中规定的所有方法,那么这个变量就实现了这个接口,可以称为这个接口类型的变量。
:::
使用值接收者实现接口与使用指针接收者实现接口的区别?
使用值接收者实现接口,结构体类型和结构体指针类型的变量都能保存。
- 因为Go语言中有对指针类型变量求值的语法糖,指针内部(如
<font style="color:rgb(68, 68, 68);">&cat</font>)会自动求值<font style="color:rgb(68, 68, 68);background-color:rgb(248, 248, 248);">*cat</font>。
指针接收者实现接口,只能存结构体指针类型的变量
- 变量只能存储指针类型的值
实现了接口有什么用呢?
接口类型变量能够存储所有实现了该接口的实例。 例如上面的示例中,Sayer类型的变量能够存储dog和cat类型的变量。
这里其实能感觉出来和java里面接口的相似之处了。 类型看左边,实现看右边
func main() {var x Sayer // 声明一个Sayer类型的变量xa := cat{} // 实例化一个catb := dog{} // 实例化一个dogx = a // 可以把cat实例直接赋值给xx.say() // 喵喵喵x = b // 可以把dog实例直接赋值给xx.say() // 汪汪汪}
Tips: 观察下面的代码,体味此处_的妙用
// 摘自gin框架routergroup.gotype IRouter interface{ ... }type RouterGroup struct { ... }var _ IRouter = &RouterGroup{} // 确保RouterGroup实现了接口IRouter
