https://geektutu.com/post/quick-golang.html

接口(interfaces)

一般而言,接口定义了一组方法的集合,接口不能被实例化,一个类型可以实现多个接口。

PersongetName()getAge()
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
type Person interface {
getName() string
}

type Student struct {
name string
age int
}

func (stu *Student) getName() string {
return stu.name
}

type Worker struct {
name string
gender string
}

func (w *Worker) getName() string {
return w.name
}

func main() {
var p Person = &Student{
name: "Tom",
age: 18,
}

fmt.Println(p.getName()) // Tom
}
Student
(*Student).getName()
1
*Student does not implement Person (missing getName method)
(*Worker).getName()
1
2
var _ Person = (*Student)(nil)
var _ Person = (*Worker)(nil)
  • 将空值 nil 转换为 *Student 类型,再转换为 Person 接口,如果转换失败,说明 Student 并没有实现 Person 接口的所有方法。
  • Worker 同上。

实例可以强制类型转换为接口,接口也可以强制类型转换为实例。

1
2
3
4
5
6
7
8
9
func main() {
var p Person = &Student{
name: "Tom",
age: 18,
}

stu := p.(*Student) // 接口转为实例
fmt.Println(stu.getAge())
}

6.3 空接口

如果定义了一个没有任何方法的空接口,那么这个接口可以表示任意类型。例如

1
2
3
4
5
6
7
func main() {
m := make(map[string]interface{})
m["name"] = "Tom"
m["age"] = 18
m["scores"] = [3]int{98, 99, 85}
fmt.Println(m) // map[age:18 name:Tom scores:[98 99 85]]
}