一、定义
接口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("小狗跳")
}
- 一个类型可以实现多个接口:比如有一个
Dog类型,既可以实现Animal接口(包含Say()、Move()等方法),也可以同时实现Pet接口(包含Feed()、Play()等方法)。就像一只狗,既属于 “动物” 这个类别,也属于 “宠物” 这个类别,具备两类的行为 - 一个接口可以被多个类型实现:比如
Animal接口,不仅Dog可以实现,Cat、Bird等类型也都可以实现,只要它们都包含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
四、泛型
泛型是一种编程特性,它允许开发者在定义函数、类型(如结构体、接口)时不指定具体的数据类型,而是使用类型参数(如 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)
}