3.4.3 组合
struct是Go语言程序中最常用的数据类型,前面已经说过它有些像其他语言中的class,所以此处再来探讨一下Go语言的特性。Go语言是支持面向对象编程的,可是却没有继承。那么,Go语言是通过什么方法实现类似继承的效果的呢?答案就是通过struct的组合。Go语言推荐使用struct组合来达到代码复用效果,并以此实现类似继承的功能。
struct组合涉及多个struct,一个struct可以含有其他struct,以此达到复用效果。
注意
虽然struct可以含有其他struct,但不可以含有它自身,也就是说一个struct的成员不可以是本struct。不过,struct内的成员可以是指向自己的指针。
下面通过代码来看一下struct组合的使用:
book/ch03/3.4/comli/main.go
1. package main
2.
3. import "fmt"
4.
5. type Person struct {
6. Name string
7. Gender,Age int
8. }
9.
10. type Employee struct {
11. p Person
12. Salary int
13. }
14.
15. type Student struct {
16. Person
17. School string
18. }
19.
20. func main() {
21. e := Employee{p:Person{"Scott",1,30},Salary:1000}
22. fmt.Println(e)
23. fmt.Println(e.p.Name)
24.
25. var s Student
26. s.Name = "Billy" //相当于 s.Person.Name = "Billy"
27. s.Gender = 1 //相当于 s.Person.Gender = 1
28. s.Age = 6 //相当于 s.Person.Age = 6
29. s.School = "定慧里小学"
30. fmt.Println(s)
31. }
32.
33. //以下是运行结果
34. {{Scott 1 30} 1000}
35. Scott
36. {{Billy 1 6} 定慧里小学}
第5行至第8行,定义一个struct Person。
第10行至第13行,定义Employee struct,里面包含了Person结构体,把Person作为Employee的一个字段。
第21行至第23行测试了Employee的使用。先定义变量e,请注意查看struct组合初始化的方式,然后打印整个变量,结合第34行可以看到,这样使用可以打印所有信息。第23行展示了如果我们要访问struct组合内部的一个字段该如何操作,结合第35行的结果可以看到,可以通过外层struct直接访问组合内部struct的属性。不过这种访问struct组合具体字段的方式比较复杂,需要写多个点。接下来看一下匿名字段的使用。
第15行至第18行,定义一个student struct。注意第16行,这是匿名字段的用法,编程时只需要写类型即可。
第25行至第30行再次展示了匿名字段的用法,当要访问内部结构体的字段时,不需要按照完整路径去写,在结构体下直接访问内部结构体的字段即可。注意,匿名字段的写法也可以使用后面备注的方式替换。
注意
匿名字段的使用让内部结构体的访问更为简洁便利,但要注意的是,不要出现字段名称重复的情况,那样会让Go语言在编译的时候因名称混乱导致错误。
其实,struct的用法更为灵活,可以在定义的时候使用tags,使struct字段与JSON和数据库字段建立对应关系,这些都会在后文进行介绍。