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
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内置函数数目

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
|
package main import ( "fmt" ) func main() { 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
|
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, "不存在") }
|
④ map的遍历:map使用for-range的结构遍历(不能使用传统for循环)
1 2 3 4 5
| for key, value := range myMap { fmt.Println(key, value) }
|
⑤ map的长度
1 2 3 4 5 6 7 8 9
| func len
func len(v Type) int 内建函数len返回v的长度,这取决于具体类型: 数组:v中元素的数量 数组指针:*v中元素的数量(v为nil时panic) 切片、映射:v中元素的数量,若v为nil,len(v)即为零 字符串:v中字节的数量 通道:通道缓存中队列(未读取)元素的数量;若v为nil,len(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
|
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"
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)
map2 := make(map[string]string) map2["jason"] = "cool" map2["abosh"] = "fsngla" map2["good"] = "gnslg" map2["black"] = "wertj" fmt.Println(map2)
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
|
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
|
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 学生的地址是北京
|