接口
在go中,接口是一种类型,抽象类型
接口interface
是一组方法method
的组合
01 基础
- 1 定义接口
语法
type 接口名 interface {
函数名1(参数名 参数类型)(返回值名 返回值类型)
函数名2(参数名 参数类型)(返回值名 返回值类型)
}
注意:
1 接口名一般以er
结尾,一般首字母大写
2 函数名命名规范:驼峰体,首字母大写
3 参数名和返回值名可以省略
package main
import "fmt"
func main() {
InterfaceFunc()
}
type People struct {
Name string
}
type Inter interface { // 接口Inter
say()
}
func (p People) say() { // 实现了接口的方法
fmt.Println("ok")
fmt.Println(p.Name)
}
func InterfaceFunc() {
var s Inter
a := People{
Name: "lynn",
}
s = a
s.say()
}
- 2 实现接口
对象实现了接口的所有方法,那么对象就实现了该接口,可以把该对象赋值给接口对象,接口对象可以调用接口中的方法
package main
import "fmt"
func main() {
InterfaceFunc()
}
type People struct {
Name string
}
type Inter interface { // 接口Inter
say()
}
func (p People) say() { // 实现了接口的所有方法,也就是实现了接口。People结构体也可以是*People
fmt.Println("ok")
fmt.Println(p.Name)
}
func InterfaceFunc() {
var s Inter
a := People{
Name: "lynn",
}
s = a // 把实现接口的对象赋值给接口对象,相当于存储了实现接口的对象
s.say() // 调用接口的方法
}
注意:
1 实现接口所有方法的对象,就意味实现了接口,这种对象能赋值给接口变量。相当于说接口对象存储了实现该接口的对象数据
2 实现接口的方法时,结构体也可以是该结构体的指针
3 如果是结构体的指针时,接口变量只能存储对象的指针;如果是结构体,接口变量可以接收对象或者对象的指针
02 结构体和接口
结构体和接口是相互独立的。一个对象可以实现多个接口,一个接口可以被多个对象实现。
package main
import "fmt"
func main() {
StructInterface()
}
type Sayer interface {
Say(string)
}
type Eater interface {
Eat(int)
}
type People struct {
name string
}
type Pig struct {
message string
}
func (p People) Say(a string) { // People实现了Sayer接口
fmt.Println(p.name)
fmt.Println(a)
}
func (p People) Eat(a int) { // People实现了Eater接口
fmt.Println(p.name)
fmt.Println(a)
}
func (p Pig) Say(a string) { // Pig实现了Sayer接口
fmt.Println(p.message)
fmt.Println(a)
}
func (p Pig) Eat(a int) { // Pig实现了Eater接口
fmt.Println(p.message)
fmt.Println(a)
}
func StructInterface() {
peo := People{name:"mac"}
pig := Pig{message:"is 18"}
var say Sayer
say = peo
say.Say("say people")
say = pig
say.Say("say pig")
var eat Eater
eat = peo
eat.Eat(19)
eat = pig
eat.Eat(18)
}
03 接口嵌套
实现接口所有方法(包括嵌套的接口内的方法),就是实现了接口
package main
import "fmt"
func main() {
InterFaceFunc()
}
type Sayer interface {
Say()
}
type Mover interface {
Move()
Sayer
}
type People struct {
Name string
}
func (p People) Say() {
fmt.Println("say")
}
func (p People) Move() {
fmt.Println("move")
}
func InterFaceFunc() {
peo := People{Name: "mac"}
var move Mover
move = peo
move.Say()
move.Move()
}
04 空接口
空接口就是不包含方法的接口,意识是:可以存储任意类型的数据!!!
import "fmt"
func main() {
NoneInterface()
}
type All interface{}
func NoneInterface() {
var all All
name := "lynn"
all = name
fmt.Println(all)
}
利用空接口做类型判断
语法
package main
import "fmt"
func main() {
CheckType()
}
func CheckType() {
var ct interface{} // 声明实例化空接口
ct = 100 // 把要判断变量赋值给空接口实例
value, ok := ct.(int) // 如果是int类型,ok的值时true,value的值是100;否则是false和空
fmt.Println(value, ok)
}
常用方法
package main
import "fmt"
func main() {
NoneInterface()
}
type All interface{} // 空接口
func NoValue(every All)(All) { // 参数类型和返回值类型都是空接口,意味着参数和返回值可以是任意类型
return every
}
func NoneInterface() {
fmt.Println(NoValue(10)) // 参数和返回值是数字
fmt.Println(NoValue("mac")) // 参数返回值是字符串
a := []All{ // 切片的元素可以是任意类型
"mac",
10,
"ok",
}
b := map[string]All{ // map的value值,可以是任意类型
"name": "mac",
"age": 10,
}
fmt.Println(NoValue(a)) // 参数和返回值是切片
fmt.Println(NoValue(&a)) // 参数和返回值是指针
fmt.Println(NoValue(b)) // 参数和返回值是map
}
总结:
空接口类型作为:函数的参数类型、返回值类型、切片的元素类型、map的value类型等时,这些变量可以为任意类型的变量