Go的接口
理解Go的接口
在Go中其实更好理解接口的定义,接口就是对一类结构体的规范,属于这个接口的结构体都实现了一些方法
但是在Go中其实是一种隐式的方法,并没有像Java一样用implement的方法去实现一个接口
只要你实现了一个接口的所有方法,那么你就实现了这个接口,其实某种程度上也是Go多态的体现
Go接口的定义方式
// Animal 定义了是Biter又是Sayer的类型
type Animal interface {
Biter
Sayer
}
// Biter 定义了一种类型,一种抽象的类型,只要实现了say()这个方法的类型都可以成为sayer类型
type Biter interface {
// 方法名字(参数) 返回值
bite()
}
type Sayer interface {
say()
}
Go中实现一个接口
隐式实现即可
type Dog struct {
}
func (dog Dog) bite() {
fmt.Println("狗咬人")
}
func (dog Dog) say() {
fmt.Println("saysaysay!")
}
“多态”
Go说是一种没有多态的语言,但是这也可以理解成多态
func bited(animal Biter) {
animal.bite()
}
var animal Biter
animal = &Cat{}
bited(animal) // #狗咬人
接口值
接口值是维护了接口动态类型以及接口动态具体值的
如果一个接口类型为空,值也空,它是nil的,但是如果它类型不为空,即使维护的接口值是空的,它也不是nil
在Go中对nil的判断要谨慎,比如slice,它注定不是nil的,就要同时用len(slice)去判断它是否非空
空接口类型判断
空接口的存在很像是Java中的Object,由于它的存在,它可以用在Map里面当Value,也可以作为函数的参数来使用
同时它的类型也要好好处理,不然的话容易出错, 下面这就是接口类型断言的办法
x.(type)
// 类型断言, 这里会返回结果的,通过OK去判断是不是这个类型
if ret, ok := x.(Biter); ok {
fmt.Println(ret)
} else {
fmt.Println("", ret)
}
switch v := x.(type) {
case Animal:
fmt.Println("Animal", v)
case Biter:
fmt.Println("Biter", v)
default:
fmt.Println("don't know", v)
}