Go:接口一些特性

最近在刷题的时候,注意到接口的一些特性。

空接口的作用

在调用一些库函数的时候,经常会注意到函数参数里面会带有一个空接口,但是实际调用的时候却可以传别的类型进去。后面查的资料,才发现:

  1. 接口在go里面的实现是隐式的,也就是说只要是实现了所有接口里面定义的方法,那么就可以认为实现了接口
  2. 上面一条说了实现接口的条件,但是注意需要知道是结构体才能实现接口。也就是说函数的实现必须要有接收者,才会认为这个函数是接口的实现,不然的话只是一个普通的方法
  3. 既然接口有了实现的主体和实现的条件,那么空接口的作用也就出来了:空接口没有定义任何方法的接口类型。因此任何类型都可以视为实现了空接口。也正是因为空接口类型的这个特性,空接口类型的变量可以存储任意类型的值。
  4. 当然在一些内建函数的参数上面,我们会发现参数是any,但实际上点进去查看源码,发现其实就是type的空接口:
  5. 空接口既然可以储存任意类型的值,实际作用肯定不止函数参数这一个地方,比如map的value:map[string]interface{}

接口的实现

上面讲到了只要结构体实现的条件,正常来说结构体直接实现接口的方法即可。但是,我也发现一些比较骚的实现也可以实现接口,比如:组合结构体、结构体继承。

// WashingMachine 洗衣机
type WashingMachine interface {
	wash()
	dry()
}

// 甩干器
type dryer struct{}

// 实现WashingMachine接口的dry()方法
func (d dryer) dry() {
	fmt.Println("甩一甩")
}

// 海尔洗衣机
type haier struct {
	dryer //======嵌入甩干器结构体,变相的实现了接口的dry方法=============
}

// 实现WashingMachine接口的wash()方法
func (h haier) wash() {
	fmt.Println("洗刷刷")
}

同样还是上面的例子,但是这次用结构体的继承也可以变相实现接口的所有方法:

// WashingMachine 洗衣机
type WashingMachine interface {
	wash()
	dry()
}

// 甩干器
type dryer struct{}

// 实现WashingMachine接口的dry()方法
func (d dryer) dry() {
	fmt.Println("甩一甩")
}

// 海尔洗衣机
type haier struct {
	*dryer //=======嵌入甩干器,继承dryer变相实现dry方法==========
}

// 实现WashingMachine接口的wash()方法
func (h haier) wash() {
	fmt.Println("洗刷刷")
}

接口变量

正如标题,接口可以作为一个变量,然后对他进行赋值操作。

// WashingMachine 洗衣机
type WashingMachine interface {
	wash()
}

// 甩干器
type dryer struct{}

// 实现WashingMachine接口的dry()方法
func (d dryer) dry() {
	fmt.Println("甩一甩")
}

func main(){
  var w WashingMachine
  d := dryer{}
  w = d
//接口变量调用dryer结构体实现的接口方法
  w.dry()
}

另外一个类似的应用就是在函数参数里面:

//接口作为函数参数
func runWash(w WashingMachine) {
  fmt.Println("run wash func")
}

func main(){
  d := dryer{}
//只要是实现了WashingMachine接口的都可以传参进去,如果还有另外的什么结构体a、b什么的都可以传!!!
  runWash(d)
}

资料参考

posted @ 2023-06-26 17:27  CodeWater  阅读(6)  评论(0编辑  收藏  举报