Go语言基础之接口

59 阅读3分钟
在Go语言中接口(interface)是一种类型,一种抽象的类型。
相较于之前章节中讲到的那些具体类型(字符串、切片、结构体等)更注重“我是谁”,
接口类型更注重“我能做什么”的问题。
接口类型就像是一种约定——概括了一种类型应该具备哪些方法,
在Go语言中提倡使用面向接口的编程方式实现解耦
接口是一种由程序员来定义的类型,一个接口类型就是一组方法的集合,它规定了需要实现的所有方法


### 接口的定义
type 接口类型名 interface{
    方法名1( 参数列表1 ) 返回值列表1
    方法名2( 参数列表2 ) 返回值列表2
    …
}
### 实现接口的条件
接口就是规定了一个**需要实现的方法列表**,在 Go 语言中一个类型只要实现了接口中规定的所有方法,
那么我们就称它实现了这个接口。

### 为什么要使用接口? 面向接口编程
在电商系统中我们允许用户使用多种支付方式(支付宝支付、微信支付、银联支付等),
我们的交易流程中可能不太在乎用户究竟使用什么支付方式,
只要它能提供一个实现支付功能的`Pay`方法让调用方调用就可以了

### 接口类型变量
一个接口类型的变量能够存储所有实现了该接口的类型变量

## 值接收者和指针接收者
1、值接收者实现接口
使用值接收者实现接口之后,不管是结构体类型还是对应的结构体指针类型的变量都可以赋值给该接口变量
2、指针接收者实现接口
结构体类型变量不能赋值给接口变量、结构体指针类型才能

## 类型与接口的关系
一个类型可以同时实现多个接口,而接口间彼此独立,不知道对方的实现
### 多种类型实现同一接口
Go语言中不同的类型还可以实现同一接口


## 接口组合
接口与接口之间可以通过互相嵌套形成新的接口类型

## 空接口
空接口是指没有定义任何方法的接口类型。因此任何类型都可以视为实现了空接口。
也正是因为空接口类型的这个特性,空接口类型的变量可以存储任意类型的值
var x interface{} // 声明一个空接口类型变量x
type Any interface{}
接口的`动态类型``动态值`
接口值保存的动态类型相同,但是这个动态类型不支持互相比较(比如切片),那么对它们相互比较时就会引发panic

## 类型断言
x.(T)
第一个参数是`x`转化为`T`类型后的变量,第二个值是一个布尔值,
若为`true`则表示断言成功,为`false`则表示断言失败。
// justifyType 对传入的空接口类型变量x进行类型断言
func justifyType(x interface{}) {
	switch v := x.(type) {
	case string:
		fmt.Printf("x is a string,value is %v\n", v)
	case int:
		fmt.Printf("x is a int is %v\n", v)
	case bool:
		fmt.Printf("x is a bool is %v\n", v)
	default:
		fmt.Println("unsupport type!")
	}
}