本篇文章分析go中结构体使用细节,结构体、组合结构体、OOP中继承的使用。
为什么要写这篇文章?
因为在使用go的过程中我总是把组合结构体和结构体继承的声明方式搞混淆,因此写这篇博文来提醒自己注意两者的区别。
一、 结构体介绍:
1、概述
一个结构体(struct)就是一个字段的集合。
type Vertex struct {
X int
Y int
}
func main() {
fmt.Println(Vertex{1, 2})
}
2、结构体字段的调用
type Vertex struct {
X int
Y int
}
func main() {
v := Vertex{1, 2}
v.X = 4
fmt.Println(v.X)
}
3、结构体指针
结构体字段可以通过结构体指针来访问。
如果定义一个指向结构体的指针 p,那么可以通过 (*p).X 来访问其字段 X。但是这样写比较麻烦,因此go语言也允许我们使用隐式间接引用,直接写 p.X 就可以。
type Vertex struct {
X int
Y int
}
func main() {
v := Vertex{1, 2}
p := &v
p.X = 1e9
fmt.Println(v)
}
二、 普通结构体使用
创建结构体变量和访问结构体字段的方式有四种
方式1-直接声明
案例演示: var s student
方式2-{}字面量
案例演示: var s student = student {字段值1, 字段值2.. }
方式3-使用new关键字
案例: var s*= new (student )
方式4-指针
案例: var s*student = &student {}
代码如下:
/*结构体声明方式4种*/
type student struct {
name string
age int
score float64
}
//方法显示信息
func (s *student) showInfor() {
fmt.Printf("学生信息如下:姓名:%s 年龄:%d 分数:%f \n",
s.name,s.age,s.score)
}
func ExtendDemo4() {
/*结构体声明方式1-直接声明*/
var s student
s.name = "赵柳"
s.age = 16
s.score = 90
s.showInfor()
/*结构体声明方式2-字面量*/
s1 := student{"黄晓明",18,45}
s2 := student{name : "赵丽颖",age : 18, score : 30}
s1.showInfor()
s2.showInfor()
/*结构体声明方式3-new关键字*/
var s3 *student = new (student)
//标准的赋值方法
//因为上面的写法通过指针去访问字段的标准方式,比较麻烦,编译器的底层做了优化
// (*s3).name 等价于 s3.name
// 即:编译器,会自动带 s3.name ,执行时,加上 * ,就是 (*s3).name
(*s3).name = "刘备"//标准用法
s3.age = 32 //简写用法
s3.score = 90
s3.showInfor()
/*结构体声明方式3-指针*/
var s4 *student = &student{"张宇",18,45}
s4.showInfor()
}
测试结果:
学生信息如下:姓名:赵柳 年龄:16 分数:90.000000
学生信息如下:姓名:黄晓明 年龄:18 分数:45.000000
学生信息如下:姓名:赵丽颖 年龄:18 分数:30.000000
学生信息如下:姓名:刘备 年龄:32 分数:90.000000
学生信息如下:姓名:张宇 年龄:18 分数:45.000000
三、组合结构体使用
1、什么是组合结构体?
如果一个struct嵌套了一个有名结构体,这种模式就是组合结构体,
type student struct {
name string
age int
score float64
}
type romm struct{//组合结构体
s student
num int
}
2、组合结构体使用
代码如下
/*
如果一个struct嵌套了一个有名结构体,这种模式就是组合,
如果是组合关系,那么在访问组合的结构体的字段或方法时,必须带上结构体的名字
*/
type student struct {
name string
age int
score float64
}
type romm struct{//组合结构体
s student
num int
}
func ExtendDemo1() {
/*组合结构体声明方式1*/
var romms romm
// romms.name ="ds" //访问方式是错误的
romms.s.name = "小米粒"
romms.s.age = 34
romms.s.score = 60
romms.num = 30
fmt.Println(romms)
/*组合结构体声明方式2*/
romms2 := romm{
s : student{"大米粒",23,80},
num : 40,
}
fmt.Println(romms2)
/*组合结构体声明方式3*/
romms3 := romm{student{"大米粒",23,80},40}
fmt.Println(romms3)
}
测试结果:
{{小米粒 34 60} 30}
{{大米粒 23 80} 40}
{{大米粒 23 80} 40}
在结构体使用时要特别注意组合结构体和继承结构体的区别:继承结构体与组合结构体的区别在于 名称前面有没有别名
type romm struct{//组合结构体
s student
num int
}
type collegeStudent struct{//继承
student
writeThesis bool
}
同时要注意声明方式的不同:
//组合结构体声明
middlep1 :=middleStudentPoint{
student : &student{
name : "小龙女",
age : 44,
score : 50,
},
college :true,}
//结构体继承声明
romms2 := romm{
s : student{"大米粒",23,80},
num : 40,
}
四、OOP中结构体继承
结构体的继承是go面向对象的一部分.
type student struct {
name string
age int
score float64
}
func (s *student) setGrade(score float64) {
s.score=score
}
func (s *student) showInfor() {
fmt.Printf("学生信息如下:姓名:%s 年龄:%d 分数:%f \n",
s.name,s.age,s.score)
}
type collegeStudent struct{
student
writeThesis bool
}
type middleStudent struct{
student
college bool
}
type middleStudentPoint struct{
*student
college bool
}
func (c *collegeStudent) graduation() {
res := "未毕业"
if c.writeThesis {
res = "已毕业"
}
fmt.Printf("毕业信息如下:姓名:%s 年龄:%d 分数:%f 是否毕业: %s\n",
c.name,c.age,c.score,res)
}
func (p *primaryStudent) showInfor() {
fmt.Printf("学生信息如下:姓名:%s 年龄:%d 分数:%f \n",
p.name,p.age,p.score)
}
func ExtendDemo() {
// 匿名结构体字段访问可以简化
/*继承结构体的声明方式1*/
var college collegeStudent
college.score = 70.5
college.name = "张三"
college.age = 23
college.showInfor()
college.student.setGrade(59.1)
college.showInfor()
college.writeThesis = true
college.graduation()
/*继承结构体(匿名结构体)的声明方式2*/
middle := middleStudent{
student : student{
name : "王辉",
age : 44,
score : 50,
},
college :true,
}
/*继承结构体的声明方式3*/
middle1 := middleStudent{
student{ "王辉",44,90,},true,
}
middle.showInfor()
middle1.showInfor()
/*指针*/
/*继承结构体的声明方式4*/
middlep :=middleStudentPoint{&student{ "刘亦菲",44,90,},true,}
/*继承结构体的声明方式5*/
middlep1 :=middleStudentPoint{
student : &student{
name : "小龙女",
age : 44,
score : 50,
},
college :true,}
middlep.showInfor()
middlep1.showInfor()
}
测试结果:
学生信息如下:姓名:张三 年龄:23 分数:70.500000
学生信息如下:姓名:张三 年龄:23 分数:59.100000
毕业信息如下:姓名:张三 年龄:23 分数:59.100000 是否毕业: 已毕业
学生信息如下:姓名:王辉 年龄:44 分数:50.000000
学生信息如下:姓名:王辉 年龄:44 分数:90.000000
学生信息如下:姓名:刘亦菲 年龄:44 分数:90.000000
学生信息如下:姓名:小龙女 年龄:44 分数:50.000000