2022-5-6 实习Day29

1、汇款业务-解付业务单元测试文档编写。 –3小时 80%
2、汇款业务对私交易测试,存在工作流问题。–2小时 80%
3、5/5bug文档测试校验,验证关闭–2小时 100%

Golang编程学习(part 24)

1、map的基本概念

① map是 key-value 数据结构,又称为字段或者关联数组。类似其他编程语言的集合
② 基本语法:var 变量名 map[keytype]valuetype
key可以是什么类型?Golang中map的key可以是很多种类型,比如bool数字string指针channel,还可以是只包含前面几个类型的接口结构体数组
通常 key 为 int、string(注意:slice,map还有function不可以,因为这几个没法用==来判断)
valuetype可以是什么类型?valuetype 的类型和 key 基本一样,通常为:数字(整数,浮点数),string,map,struct

2、map声明的举例

1
2
3
4
var a map[string]string
var b map[string]int
var c map[int]string
var d map[string]map[string]string
注意:声明是不会分配内存的,初始化需要 make,分配内存后才能赋值和使用
1
2
3
4
5
6
7
8
9
10
var a map[string]string

//在使用map之前,需要先make,make的作用就是给map分配数据空间
a = make(map[string]string, 10)

a["no1"] = "宋江"
a["no2"] = "吴用"
a["no3"] = "武松"
a["no4"] = "赵四"
fmt.Println(a)
对上面代码的说明
1)map在使用前一定要 make
2)map的key是不能重复的,如果重复了,则以最后这个 key-value 为准
3)map的value是可以相同的
4)map的key-value是无序的(高版本是按顺序了)
5)make内置函数数目

image-20220511001749364

3、map的使用

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
// 第一种使用方式
var a map[string]string
a = make(map[string]string, 10)
a["no1"] = "宋江"
a["no2"] = "吴用"
a["no3"] = "武松"
a["no4"] = "赵四"

// 第二种使用方式
cities := make(map[string]string)
cities["no1"] = "北京"
cities["no2"] = "天津"
cities["no3"] = "上海"
fmt.Println(cities)

// 第三种方式
heroes := map[string]string{
"hero1": "宋江",
"hero2": "卢俊义",
"hero3": "吴用",
}
heroes["hero4"] = "林冲"
fmt.Println(heroes)

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
// 课堂练习:我们要存放3个学生信息,每个学生有name和sex信息
// 思路: map[string]map[string]string
package main
import (
"fmt"
)
func main() {
// 先对最大的进行空间分配,然后再对里面的map继续分配空间
stu := make(map[string]map[string]string)

stu["学生1"] = make(map[string]string)
stu["学生1"]["name"] = "tom"
stu["学生1"]["sex"] = "男"
stu["学生1"]["address"] = "北京长安"

stu["学生2"] = make(map[string]string)
stu["学生2"]["name"] = "mary"
stu["学生2"]["sex"] = "女"
stu["学生2"]["address"] = "上海黄浦江"

fmt.Println(stu)
fmt.Println(stu["学生1"])
fmt.Println(stu["学生1"]["address"])
}

map[学生1:map[address:北京长安 name:tom sex:男] 学生2:map[address:上海黄浦江 name:mary sex:女]]
map[address:北京长安 name:tom sex:男]
北京长安

4、map的增删改查

① map的增加和更新:map[“key”] = value,如果key还没有,就是增加,如果key存在就是修改
1
2
3
4
5
6
7
8
9
10
11
cities := make(map[string]string)
cities["no1"] = "北京"
cities["no2"] = "天津"
cities["no3"] = "山西"
fmt.Println(cities)
cities["no1"] = "江苏"
fmt.Println(cities)

map[no1:北京 no2:天津 no3:山西]
map[no1:江苏 no2:天津 no3:山西]

② map的删除:delete(map, “key”),delete是一个内置函数,如果key存在,就删除该key-value,如果不存在,不操作但是也不会报错。
1
2
3
4
func delete

func delete (m map[Type]Type1, key Type)
内建函数delete按照指定的键将元素从映射中删除,若m为nil或无此元素,delete不进行操作。

案例:

1
2
3
4
5
6
7
8
9
10
myMap := make(map[string]string)
myMap["c1"] = "上海"
myMap["c2"] = "北京"
myMap["c3"] = "杭州"
fmt.Println(myMap)
delete(myMap, "c1")
fmt.Println(myMap)

map[c1:上海 c2:北京 c3:杭州]
map[c2:北京 c3:杭州]
细节说明:如果我们要删除map的所有key,没有一个专门的方法一次删除,可以遍历一下key,逐个删除或者 map = make(…),make一个新的,让原来的成为垃圾,被gc回收。
1
2
3
4
5
6
7
8
9
10
11
12
13
// 如果希望一次性删除所有的key
// 1、遍历所有的key,逐一删除
// 2、直接make一个新的空间
myMap := make(map[string]string)
myMap["c1"] = "上海"
myMap["c2"] = "北京"
myMap["c3"] = "杭州"
fmt.Println(myMap)
myMap = make(map[string]string)
fmt.Println(myMap)

map[c1:上海 c2:北京 c3:杭州]
map[]
③ map的查找
1
2
3
4
5
6
7
8
9
s, ok := myMap["c1"]
if ok {
fmt.Println(s, "存在")
} else {
fmt.Println(s, "不存在")
}

// 上海 存在
// 如果存在就会返回true,否则返回false
④ map的遍历:map使用for-range的结构遍历(不能使用传统for循环)
1
2
3
4
5
for key, value := range myMap {
fmt.Println(key, value)
}

// 如果遍历一个map套map的结构,那就将外层的value作为内层遍历的元素就行
⑤ map的长度
1
2
3
4
5
6
7
8
9
func len

func len(v Type) int
内建函数len返回v的长度,这取决于具体类型:
数组:v中元素的数量
数组指针:*v中元素的数量(v为nilpanic
切片、映射:v中元素的数量,若v为nillen(v)即为零
字符串:v中字节的数量
通道:通道缓存中队列(未读取)元素的数量;若v为nillen(v)即为0

5、map的切片

基本介绍:切片的数据类型如果是map,我们称为 slice of map,这样使用则map个数就可以动态变化了。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
// 使用一个map来记录monster的信息 name 和 age,也就是说一个monster对应一个map,并且妖怪的个数可以动态增加
// 1、声明一个map切片()
monsters := make([]map[string]string, 2)
monsters[0] = make(map[string]string, 2)
monsters[0]["name"] = "牛魔王"
monsters[0]["age"] = "500"

monsters[1] = make(map[string]string, 2)
monsters[1]["name"] = "琵琶精"
monsters[1]["age"] = "1000"

// 2、试一下切片的append函数, 可以动态的增加monster
newMonster := map[string]string{
"name": "新的妖怪 ~ 火云邪神",
"age": "200",
}
monsters = append(monsters, newMonster)
fmt.Println(monsters)

6、map的排序

① Golang中没有一个专门的方法针对map的key进行排序
② Golang中的map默认是无序的,注意也不是按照添加的顺序存放到,你每次遍历,得到的输出可能不一样(这条守则到新版sdk中不适用了)
③ Golang中map的排序,是先将key进行排序,然后根据key值遍历输出即可
1
2
3
4
5
6
7
8
9
10
11
12
13
14
map1 := make(map[int]int)
map1[1] = 3
map1[2] = 8
map1[8] = 4
map1[4] = 6
fmt.Println(map1) // map[1:3 2:8 4:6 8:4]

map2 := make(map[string]string)
map2["jason"] = "cool"
map2["abosh"] = "fsngla"
map2["good"] = "gnslg"
map2["black"] = "wertj"
fmt.Println(map2) // map[abosh:fsngla black:wertj good:gnslg jason:cool]

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
// 使用③中的排序方法
// 1、先将map的key放入到切片中
// 2、对切片排序
// 3、遍历切片,然后按照key来输出map的值
var keys []int
for k, _ := range map1 {
keys = append(keys, k)
}

// 排序
sort.Ints(keys)
for _, k := range keys {
fmt.Prinf("map1[%v]=%v \n", k, map1[k])
}

7、map的使用细节

① map是引用类型,遵守引用类型传递的机制,在一个函数接收map,修改后会直接修改原来的map
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
package main
import (
"fmt"
)
func main() {
map1 := make(map[int]int)
map1[1] = 90
map1[2] = 88
map1[10] = 1
map1[20] = 2
fmt.Println(map1)
modify(map1)
fmt.Println(map1)
}
func modify(map1 map[int]int) {
map1[10] = 900
}

map[1:90 2:88 10:1 20:2]
map[1:90 2:88 10:900 20:2]

② map的容量达到后,再向map增加元素会自动扩容,并不会发生panic,也就是说map能动态的增长键值对(key-value)
③ map的value也经常使用struct类型,更适合管理复杂的数据(比前面value是一个map更好)
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
// 1、map的key为学生的学号,是唯一的
// 2、map的value为结构体,包含学生的 名字,年龄,地址
students := make(map[string]Student)
stu1 := Student{name: "tom", age: 25, address: "上海"}
stu2 := Student{name: "mary", age: 22, address: "北京"}
students["no1"] = stu1
students["no2"] = stu2
fmt.Println(students)

// 遍历各个学生信息
for k, v := range students {
fmt.Printf("学生的编号是%v \n", k)
fmt.Printf("学生的名字是%v \n", v.name)
fmt.Printf("学生的年龄是%v \n", v.age)
fmt.Printf("学生的地址是%v \n", v.address)
fmt.Println()
}

map[no1:{tom 25 上海} no2:{mary 22 北京}]
学生的编号是no1
学生的名字是tom
学生的年龄是25
学生的地址是上海

学生的编号是no2
学生的名字是mary
学生的年龄是22
学生的地址是北京