1. struct结合容器使用
1.1 struct基础知识
- Go语言中提供了对struct的支持,struct,中文翻译称为结构体,与数组一样,属于复合类型,并
非引用类型
。 - Go语言的struct,与C语言中的struct或其他面向对象编程语言中的类(class)类似,可以定义字段(属性)和方法,但也有很不同的地方,需要深入学习,才能区分他们之间的区别。
注意复合类型与引用类型之间的区别,这应该也是
值传递
和引用传递
的区别吧。
1.2 strcut + slice + map使用
需求说明:
1.数据实体是对象:student{id, name, society, age, class}
2.数据源给定表1和表2,类型:slice,[]student
, 例如:[student{}, student{}]
3.期望以较低的时间复杂度
将表1和表2的数据并入表1
package main
import (
"fmt"
)
type Student struct {
Id string
Name string
Society string
Age int
Class string
}
func main() {
/**
需求:将表1和表2数据聚合到表1中
*/
//1. 表1
studentList1 := make([]*Student, 0)
data1 := Student{Id: "001", Name: "小明", Society: "轮滑社"}
data2 := Student{Id: "002", Name: "小红", Society: "轮滑社"}
data3 := Student{Id: "003", Name: "小兰", Society: "轮滑社"}
studentList1 = append(
studentList1,
&data1,
&data2,
&data3,
)
//2. 表2
studentList2 := make([]*Student, 0)
data4 := Student{Id: "001", Age: 18, Class: "1班"}
data5 := Student{Id: "002", Age: 17, Class: "2班"}
data6 := Student{Id: "004", Age: 16, Class: "3班"}
studentList2 = append(
studentList2,
&data4,
&data5,
&data6,
)
//2. 创建速查表,快速统计数据
studentSet := make(map[string]*Student)
for _, stu := range studentList1 {
studentSet[stu.Id] = stu
}
for _, stu := range studentList2 {
//3. 查表, 并修改表1中的数据
if _, ok := studentSet[stu.Id]; ok {
fmt.Printf("查表:%+v\n", studentSet[stu.Id])
//已存在
var student = studentSet[stu.Id]
//3.1 student已存在,刷新信息
student.Age = stu.Age
student.Class = stu.Class
} else {
fmt.Printf("表中不存在:%+v\n", studentSet[stu.Id])
//3.2 student不存在,新增student到list1中
studentList1 = append(studentList1, stu)
}
}
fmt.Println("--------------------------------")
for _, data := range studentList1 {
fmt.Printf("%+v\n", data)
}
}
输出:成功合并数据到表1
查表:&{Id:001 Name:小明 Society:轮滑社 Age:0 Class:}
查表:&{Id:002 Name:小红 Society:轮滑社 Age:0 Class:}
表中不存在:<nil>
--------------------------------
&{Id:001 Name:小明 Society:轮滑社 Age:18 Class:1班}
&{Id:002 Name:小红 Society:轮滑社 Age:17 Class:2班}
&{Id:003 Name:小兰 Society:轮滑社 Age:0 Class:}
&{Id:004 Name: Society: Age:16 Class:3班}
1.3 踩坑描述
由于struct是基础数据类型,而非引用数据类型,在传入容器时,应该使用
指针结构体 *student
,
问题点1:在存取表1和表2数据时,slice存取的struct副本
,而非指针结构体
问题点2:在使用map记录历史student时,value存取的是struct副本
,而非指针结构体
现象描述:在未使用指针结构体时,每次更新数据操作对struct副本
进行更新,并未更新到原struct
上,导致表1的记录不更新
2. go编译时改变变量值
todo