接口

75 阅读2分钟

一、定义

接口interface是一种类型,描述了方法的集合,但只是抽象行为的定义,没有实现

type 接口名 interface{
//抽象行为
}

传说中的中看不中用,差不多先理解这个意思

二、使用

1. 定义接口

type Animal interface{
//动物可以说话
	Say()
//动物可以移动
	Move()
//动物可以跳
	Jump()
}

2. 实现接口

规则:实现接口的方法名、参数、返回值和数量必须和接口定义的方法完全一样

type dog struct{
}
func (d *dog) Move(){
	fmt.Println("小狗动")
}
func (d *dog) Say(){
	fmt.Println("小狗汪")
}
func (d *dog) Jump(){
	fmt.Println("小狗跳")
}

image.png

  • 一个类型可以实现多个接口:比如有一个 Dog 类型,既可以实现 Animal 接口(包含 Say()Move() 等方法),也可以同时实现 Pet 接口(包含 Feed()Play() 等方法)。就像一只狗,既属于 “动物” 这个类别,也属于 “宠物” 这个类别,具备两类的行为
  • 一个接口可以被多个类型实现:比如 Animal 接口,不仅 Dog 可以实现,CatBird 等类型也都可以实现,只要它们都包含 Say()Move() 等方法。就像 “动物” 这个接口,狗、猫、鸟都能属于它,只要具备动物的共同行为
  • 总之,只要符合接口实现规则就成

三、空接口

没有任何方法的接口:type 接口名 interface{}。说明任何类型都可以实现这个接口,为了方便它的使用,go提供了类型别名any

func main(){
	var a any
	a = 10
	fmt.Println(a)
	a = "还不快去学go"
	fmt.Println(a)
}

类型断言

any 本身并不知道里面存的具体类型是什么,如果我们想使用空接口中存储的值的 “具体类型行为”(比如对 int 做加减、对 string 做拼接),就必须明确告诉 Go:“这个 any 里存的是 int/string,请把它转成这个类型”

x.(T)
// x表示接口类型变量,可以是空接口 可以不是
// T表示要断言的目标类型
  • if...else
func main(){
	var x any
	x = "学go"
	v,ok := x.(string)
	if ok{
	fmt.Println(v)
	}else{fmt.Println("类型断言失败")}
}
  • switch

image.png

四、泛型

泛型是一种编程特性,它允许开发者在定义函数、类型(如结构体、接口)时不指定具体的数据类型,而是使用类型参数(如 T)来占位,在实际使用时再明确具体的类型

func max[T int | float64](x, y T) T {
    if x > y { return x }
    return y
}

func main() {
    fmt.Println(max(1, 2))       // 输出 2(T=int)
    fmt.Println(max(3.14, 2.71)) // 输出 3.14(T=float64)
}