在Golang中接口(interface)是一种类型,一种抽象的类型。接口(interface)是一组函数method的集合,Golang中的接口不能包含任何变量。
在Golang中接口中的所有方法都没有方法体,接口定义了一个对象的行为规范,只定义规范不实现。接口体现了程序设计的多态和高内聚低耦合的思想N Golang中的接口也是一种数据类型,不需要显示实现。只需要一个变量含有接口类型中的所有方法,那么这个变量就实现了这个接口。
1. 接口的定义
type 接口名 interface {
方法名1 (参数列表1) 返回值列表1
方法名2 (参数列表2) 返回值列表2
}
- 方法名:当方法名首字母是大写且这个接口类型名首字母也是大写时,这个方法可以被接口所在的包(package)之外的代码访问。
- 参数列表、返回值列表:参数列表和返回值列表中的参数变量名是可以省略
type Animal interface { Eat() Sleep() } type Person struct { Name string } func (p Person) Eat() { fmt.Printf("%s 正在吃饭 \n", p.Name) } func (p Person) Sleep() { fmt.Printf("%s 正在睡觉 \n", p.Name) } type Dog struct { Name string } func (d Dog) Eat() { fmt.Printf("%s 正在吃饭 \n", d.Name) } func (d Dog) Sleep() { fmt.Printf("%s 正在睡觉 \n", d.Name) } func main() { var person Person = Person{ Name: "小王", } var dog Dog = Dog{ Name: "小狗", } person.Eat() person.Sleep() dog.Eat() dog.Sleep() }
2. 空接口
Golang中的接口可以不定义任何方法,没有定义任何方法的接口就是空接口。空接口表示没有任何约束,因此任何类型变量都可以实现空接口。
空接口在实际项目中用的是非常多的,用空接口可以表示任意数据类型。相当于java中的object类型
var a interface{}
a = 20
a = "hello"
a = true
map的值实现空接口
使用空接口实现可以保存任意值的字典
// 定义一个值为空接口类型
var studentInfo = make(map[string]interface{})
studentInfo["userName"] = "zhangsan"
studentInfo["age"] = 15
studentInfo["isWork"] = true
3. 类型断言
一个接口的值(简称接口值)是由一个具体类型和具体类型的值两部分组成的。这两部分分别称为接口的动态类型和动态值。
如果我们想要判断空接口中值的类型,那么这个时候就可以使用类型断言,其语法格式:
x.(T)
//X:表示类型为interface{}的变量
//T:表示断言x可能是的类型
该语法返回两个参数,第一个参数是x转化为T类型后的变量,第二个值是一个布尔值,若为true则表示断言成功,为false则表示断言失败
// 类型断言
var a interface{}
a = "132"
value, isString := a.(string)
if isString {
fmt.Println("是String类型, 值为:", value)
} else {
fmt.Println("断言失败")
}
可以用来判读类型
// 定义一个方法,可以传入任意数据类型,然后根据不同类型实现不同的功能
func Print(x interface{}) {
if _,ok := x.(string); ok {
fmt.Println("string类型")
} else if _, ok := x.(int); ok {
fmt.Println("int类型")
} else {
fmt.Println("其它类型")
}
}
可以配合switch使用
func Print2(x interface{}) {
switch x.(type) {
case int:
fmt.Println("int类型")
case string:
fmt.Println("string类型")
case bool:
fmt.Println("bool类型")
default:
fmt.Println("其它类型")
}
}
4.结构体接受者
值接收者
如果结构体中的方法是值接收者,那么实例化后的结构体值类型和结构体指针类型都可以赋值给接口变量。
5. 结构体实现多个接口
type Animal1 interface {
SetName(string)
}
type Animal2 interface {
GetName()string
}
type Dog struct {
Name string
}
func (d *Dog) SetName(name string) {
d.Name = name
}
func (d Dog) GetName()string {
return d.Name
}
func main() {
var dog = &Dog{
"小黑",
}
var d1 Animal1 = dog
var d2 Animal2 = dog
d1.SetName("小鸡")
fmt.Println(d2.GetName())
}
6. 接口嵌套
在golang中,允许接口嵌套接口,我们首先创建一个 Animal1 和 Animal2 接口,然后使用Animal接受刚刚的两个接口,实现接口的嵌套。
type Animal1 interface {
SetName(string)
}
type Animal2 interface {
GetName()string
}
type Animal interface {
Animal1
Animal2
}
type Dog struct {
Name string
}
func (d *Dog) SetName(name string) {
d.Name = name
}
func (d Dog)GetName()string {
return d.Name
}
func main() {
var dog = &Dog{
"小黑",
}
// 同时实现两个接口
var d Animal = dog
d.SetName("小鸡")
fmt.Println(d.GetName())
}