1. Golang中的接口
在Go语言中接口(interface)是一种类型,一种抽象的类型。
接口(interface)定义了一个对象的行为规范, 只定义规范不实现 ,由具体的对象来实现规范的细节 。
实现接口的条件:
一个对象只要全部实现了接口中的方法 ,那么就实现了这个接口。换句话说,接口就是一个需要实现的方法列表。
2. 为什么要使用接口
下面的代码中定义了猫和狗,然后它们都会叫,你会发现main函数中明显有重复的代码
如果我们后续再加上猪、青蛙等动物的话,我们的代码还会一直重复下去
那我们能不能把它们当成“能叫的动物”来处理呢?
3. 定义一个Usber接口(从下往上转换)
定义一个 Usber 接口让 Phone 和 Computer 结构体实现这个接口
当我们要去处理同一数据类型的时候这个数据的时候,比如猫 狗是同一类数据类型。
像k8s的deployment,pod,configmap,secretd等等这些资源的时候,它都是k8s的一个资源,在获取列表的时候会对其做数据处理,比如要对其进行数据排序,那么只需要对这个接口进行排序就行了,不需要对每个资源都去写一遍排序的方法,那么这样不是很冗余吗?
4. 空接口
1. 空接口说明
- Golang中空接口也可以直接当做类型来使用,可以表示任意类型 (泛型概念,最大的特点)
- Golang 中的接口可以不定义任何方法,没有定义任何方法的接口就是空接口。
- 空接口表示没有任何约束,因此任何类型变量都可以实现空接口。
- 空接口在实际项目中用的是非常多的,用空接口可以表示任意数据类型
2. 空接口作为函数的参数
printf println是可以接受任何参数的,func Printf(format string , a ...interface{})可以看到这里可以接受任何空接口类型,...类似于切片类型。
3. 切片实现空接口
切片和map是同一类型的元素,有了空接口,在同一个切片同一个map中就可以将任何类型的数据放进去。
4. map 的值实现空接口
类型断言(从上往下转换,接口类型转化为具体类型)
- 一个接口的值(简称接口值)是由一个具体类型和具体类型的值两部分组成的。
- 这两部分分别称为接口的动态类型和动态值。(一个空接口,可以是结构体,指针,布尔各种类型。它其实是动态的,你传递什么都可以,这就叫做动态类型和动态值)
- 如果我们想要判断空接口中值的类型,那么这个时候就可以使用类型断言
- 其语法格式: x.(T)
x : 表示类型为 interface{}的变量
T : 表示断言 x 可能是的类型
断言返回两个值,一个是断言是否转化成果,一个是转化结果,注意空接口类型是空接口类型。
转化为具体类型之后,那么具体类型的方法是都可以去调用的,空接口是不能访问属性和方法的。转化为具体的类型之后就可以访问其属性和方法。
值接收者和指针接收者(节省内存)
1. 值接收者
当方法作用于值类型接收者时,Go语言会在代码运行时将接收者的值复制一份。
在值类型接收者的方法中可以获取接收者的成员值,但修改操作只是针对副本,无法修改接收者变量本身。
2. 指针接收者
- 指针类型的接收者由一个结构体的指针组成
- 由于指针的特性,调用方法时修改接收者指针的任意成员变量,在方法结束后,修改都是有效的。
- 这种方式就十分接近于其他语言中面向对象中的 this 或者 self 。
- 例如我们为 Person 添加一个 SetAge 方法,来修改实例变量的年龄。
3. 指针类型接收者
使用时机
注:并不是所有情况下都希望修改数据
- 需要修改接收者中的值
- 接收者是拷贝代价比较大的大对象
- 保证一致性,如果有某个方法使用了指针接收者,那么其他的方法也应该使用指针接收者。
从使用场景上面来说,基本上都会使用指针,如果使用了第三方的包,第三方包的某些返回值它只是一个值类型,所以第三方类型返回什么类型我们就使用什么类型,针对第三方包。