结构体扩展允许将多个结构体组合成一个新的结构体,在新的结构体中,允许像访问自己内部成员一样访问内嵌结构体的字段和方法。
结构体扩展般形式
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
|
type Student struct {
id int
name string
}
type StudentLeader struct {
Student
job string
}
func (s Student) Display() {
fmt.Printf("Student id:%d,name:%s\n", s.id, s.name)
}
func (sl StudentLeader) Display() {
fmt.Printf("Student id:%d,name:%s job %s\n", sl.id, sl.name, sl.job)
}
func main() {
var stu = Student{1001, "张三"}
stu.Display() //Student id:1001,name:张三
var stuLeader = StudentLeader{Student{1002, "李四"}, "班长"}
stuLeader.Display() //Student id:1002,name:李四 job 班长
}
|
通过结构体扩展,StudentLeader
可以访问其内嵌的Student
结构中的字段和方法,但是这两个类型本质上是不同的,而且也不是OOP中的继承关系,这一点可以看上面例子中StudentLeader
的创建过程,如果是继承关系,那么就不需要单独为内部的Student
单独创建一个结构体了。
我们再给这两个类型增加一些方法:
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
|
func (ps *Student) CopyFrom(fs Student) {
ps.id = fs.id
ps.name = fs.name
}
func (psl *StudentLeader) CopyFrom(fsl StudentLeader) {
psl.id = fsl.id
psl.name = fsl.name
psl.job = fsl.job
}
func main() {
var stu = Student{1001, "张三"}
stu.Display() //Student id:1001,name:张三
var stuLeader = StudentLeader{Student{1002, "李四"}, "班长"}
stuLeader.Display() //Student id:1002,name:李四 job 班长
var stu2 = Student{1003, "王五"}
var stuLeader2 = StudentLeader{Student{1004, "赵六"}, "学习委员"}
stu.CopyFrom(stu2)
stu.Display() //Student id:1003,name:王五
stuLeader.CopyFrom(stuLeader2)
stuLeader.Display() //Student id:1004,name:赵六 job 学习委员
//stu.CopyFrom(stuLeader2) //compile error:cannot use stuLeader2 (variable of type StudentLeader) as Student value in argument to stu.CopyFromcompilerIncompatibleAssign
stu.CopyFrom(stuLeader2.Student) //ok
stu.Display() //Student id:1004,name:赵六
}
|
当调用stu.CopyFrom(stuLeader2)
时出现编译错误,从而说明Student
和StudentLeader
不是“Is a”的关系而是“Has a”的关系,尽管后者已经拥有了前者的所有字段和方法。
BGM