当前位置: 代码迷 >> 综合 >> Go 聚合类型 结构体 struct 定义 声明 初始化 嵌入
  详细解决方案

Go 聚合类型 结构体 struct 定义 声明 初始化 嵌入

热度:47   发布时间:2023-09-30 10:25:51.0

自定义类型


在 go 语言中使用 type 声明一种新的类型 ,语法格式为:

Go 聚合类型 结构体 struct 定义 声明 初始化 嵌入

Format 可以任意内置类型、函数签名、结构体、接口

Go 聚合类型 结构体 struct 定义 声明 初始化 嵌入

Go 聚合类型 结构体 struct 定义 声明 初始化 嵌入

结构体定义 声明 初始化


为什么需要结构体?在go当中去描述复杂的实体,之前学到的数组,切片,map。数组和切片只能保存相同的数据类型,比如一组int,一组string。这些还不能描述复杂结构的实体。

所以结构体的特点是

  • go语言当中,数组可以存储同一类型的数据,在结构体当中可以为不同项定义不同数据类型。
  • 结构体目的就是把数据聚集到一起,以便更加便捷的操作这些数据

总结就是:定义不同的数据类型,并聚集在一起,描述复杂的实体。

在go中定义结构体

结构体定义使用 struct 标识,需要指定其包含的属性(名和类型),在定义结构体时可以为结构体指定结构体名(命名结构体),用于后续声明结构体变量使用

type Person struct {}

字段说明

可以是任意的类型,string int float map slice channel struct(字段当中是另外的结构体)

结构体声明和初始化

使用结构体创建的变量叫做对应结构体的实例或者对象
1) 使用结构体零值初始化结构体值对象

Go 聚合类型 结构体 struct 定义 声明 初始化 嵌入

2) 使用结构体字面量初始化结构体值对象

Go 聚合类型 结构体 struct 定义 声明 初始化 嵌入

3) 使用 new 函数进行初始化结构体指针对象

Go 聚合类型 结构体 struct 定义 声明 初始化 嵌入

4) 使用结构体字面量初始化结构体指针对象

Go 聚合类型 结构体 struct 定义 声明 初始化 嵌入

new和make


 new只能将内存初始化为0值,并且返回其指针。说白了也就是new返回的是指针。

  p1 := new(Person)fmt.Println(p1)fmt.Printf("%p",p1)

可以看到p1是一个指针。

make和new的对比

简单来说,new只分配内存,一般用于基础类型的初始化。make用于slice,map和channel的初始化。

对比表格如下:

函数名 适用范围 返回值 填充值
new new可以对所有类型进行内存分配 new返回指针 new填充零值
make make只能创建类型( slice map channel make返回引用 make填充非零值

new在结构体struct上的不同

new返回的是指针,struct返回的是值。

 

结构体访问和修改


怎么访问属性:结构体.成员名

  q := Person{Name: "jack",Age: 10,}fmt.Println(q.Name,q.Age)q.Name = "jhon"

匿名字段:就是没有字段名字,只有类型。

为啥要有匿名字段:其实模仿面向对象当中继承的功能

匿名结构体:又称内嵌结构体

type  Person struct{Name stringAge int}type Teacher struct {PersonTeacherID int
}t1 := Teacher{Person:    Person{Name: "jerry",Age: 10,},TeacherID: 0,}fmt.Printf("[TeacherID:%v],[name:%v],[age:%v]",t1.TeacherID,t1.Name,t1.Age)[TeacherID:0],[name:jerry],[age:10]

可以看到Person是匿名的,所以在访问其成员的时候直接访问就行,不需要t1.Person.name这样去访问。

匿名嵌入,访问继承来的结构体属性时候,可以加结构体的名字,也可以省略。

注意,在使用匿名结构体时候,如果匿名结构体当中成员和外面结构体成员名字相同,外面结构体成员会覆盖匿名结构体成员。

如果两个匿名结构体都有相同的成员,那么访问就要加上结构体名称。

在使用匿名组合的时候,里面成员尽量不要有冲突。

嵌入的为非匿名结构体

type TeacherNew struct {p Person TeacherID int
}t2 := TeacherNew{p:         Person{Name: "lucas",Age: 12,},TeacherID: 0,}fmt.Printf("[TeacherID:%v],[Name:%v],[Age:%v]",t2.TeacherID,t2.p.Name,t2.p.Age)[TeacherID:0],[Name:lucas],[Age:12]

可以看到不能跳过非匿名结构体的字段

结构体指针类型嵌入 

和非指针类型的不同就是零值是不同的。 

type TeacherNewNew struct {*PersonTeacherID int
}var t3 = TeacherNewNew{}fmt.Println(t3){<nil> 0}

在嵌入指针的时候一定要注意空指针的问题。

上面都是嵌入的问题,结构体嵌入的生产含义是什么?

大项目对应的复杂的配置文件

- 公共字段抽取出来,放到common结构体当中,其他不同的配置段自己去实现。

cmdb,资产系统:ecs云主机,rds云关系数据库,elb云负载均衡器

- 有一些公共字段

type Common struct {ChargingMod string  //付费模式,预付费和后付费Region string //区域Az string //可用区CreateTime time.Time  //购买时间
}type yunzhuji struct {Commonguige string //几个c几个g
}type yunshujuku struct {CommondbType string //数据库是哪一种,mysql redis
}
  相关解决方案