Map
map是key-value数据结构,又称为字段或者关联数组。
基本语法
语法:var map变量名 map[keytype]valuetype
1
2
3
4
| var a map[string]string
var a map[string]int
var a map[int]string
var a map[string]map[string]string
|
key的类型
可以是:bool、数字、string、指针、channel,还可以值包含前面几个类型的接口、结构体、数组,通常为int、string
slice、map和function不可以当做key的类型,因为这几个没法用==
来判断
value的类型
和key基本一样,通常为:数字(整数,浮点数)、string、map、struct
1
2
3
4
5
6
7
8
| //声明一个map
var a map[string]string
// 在使用map前,需要先make,make的作用个就是给map分配数据空间
a = make(map[string]string, 10)
a["str1"] = "第一个字符串"
a["str2"] = "第二个字符串"
a["str3"] = "第三个字符串"
fmt.Println(a) //map[str1:第一个字符串 str2:第二个字符串 str3:第三个字符串]
|
注意:声明是不会分配内存的,初始化需要make
分配内存后才能赋值和使用。
注意事项
- map在使用前一定要make
- map的key是不能重复,如果重复了,则以最后这个key-value为准
- map的value是可以相同的
- map的key-value是无序的
map的使用
方式一:
1
2
3
4
5
| var cities map[string]string
fmt.Println(cities) //map[]
// 分配一个map空间
cities = make(map[string]string, 10)
fmt.Println(cities) //map[]
|
方式二:
1
2
3
| // 声明直接make
var cities = make(map[string]string)
fmt.Println(cities) //map[]
|
方式三:
1
2
3
4
5
6
| // 声明直接赋值
var cities map[string]string = map[string]string{
"city1": "成都",
}
cities["city2"] = "深圳"
fmt.Println(cities) //map[city1:成都 city2:深圳]
|
map的操作
map的增加和更新
map["key"] = value
如果key不存在就是增加,存在则修改。
1
2
3
4
5
6
7
8
9
| cities := map[string]string{
"city1": "成都",
}
// 添加的key不存在,则新增
cities["city2"] = "深圳"
fmt.Println(cities) //map[city1:成都 city2:深圳]
// 添加的key存在,则修改
cities["city1"] = "北京"
fmt.Println(cities) //map[city1:北京 city2:深圳]
|
map的删除
delete(map, "key")
delete是一个内置函数,如果key存在,则删除key-value,如果key不存在,不操作,也不会报错。
1
2
3
4
5
| // 删除的key存在
delete(cities, "city1")
//删除的key不存在
delete(cities, "city3")
fmt.Println(cities) //map[city2:深圳]
|
如果要删除map的所有key,没有专门的方法一次删除,可以遍历一下key,逐个删除
1
2
3
4
5
6
7
8
9
10
| cities := map[string]string{
"city1": "成都",
"city2": "北京",
"city3": "深圳",
}
fmt.Println(cities) //map[city1:成都 city2:北京 city3:深圳]
for key, _ := range cities {
delete(cities, key)
}
fmt.Println(cities) //map[]
|
或者map = make(...)
make一个新的,让原来的成为垃圾,被gc回收
1
2
3
4
5
6
7
8
| cities := map[string]string{
"city1": "成都",
"city2": "北京",
"city3": "深圳",
}
fmt.Println(cities) //map[city1:成都 city2:北京 city3:深圳]
cities = make(map[string]string)
fmt.Println(cities) //map[]
|
map查找
cities["city1"]
获取map的值时,返回结果有两个,第一个为值,第二个为是否存在,存在返回true,反之false,通过判断第二个值可得到是否存在该key
1
2
3
4
5
6
7
8
9
10
11
| cities := map[string]string{
"city1": "成都",
"city2": "北京",
"city3": "深圳",
}
val, ok := cities["city4"]
if ok {
fmt.Printf("有 city1 key 值为%v\n", val)
} else {
fmt.Printf("没有 city1 key \n")
}
|
map的遍历
map的遍历使用for-range的结果遍历
1
2
3
4
5
6
7
8
9
10
11
12
13
14
| cities := map[string]string{
"city1": "成都",
"city2": "北京",
"city3": "深圳",
}
for key, value := range cities {
fmt.Println(key, value)
}
/*
结果:
city2 北京
city3 深圳
city1 成都
*/
|
map的长度
使用len(map)
1
2
3
4
5
6
| cities := map[string]string{
"city1": "成都",
"city2": "北京",
"city3": "深圳",
}
fmt.Println(len(cities)) //3
|
map切片
基本介绍
切片的数据类型如果是map,则我们称为slice of map,map切片,这样使用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
| // 1. 声明一个map切片
var monsters []map[string]string
monsters = make([]map[string]string, 2) //准备放两个信息
// 2. 添加第一个信息
if monsters[0] == nil {
monsters[0] = make(map[string]string, 2)
monsters[0]["name"] = "Ronin"
monsters[0]["age"] = "18"
}
fmt.Println(monsters) //[map[age:18 name:Ronin] map[]]
// 添加第二个信息
if monsters[1] == nil {
monsters[1] = make(map[string]string, 2)
monsters[1]["name"] = "Tommy"
monsters[1]["age"] = "20"
}
fmt.Println(monsters) //[map[age:18 name:Ronin] map[age:20 name:Tommy]]
// 使用append函数动态的增加map数据
// 1.先定义信息
monster := map[string]string{
"name": "Desire",
"age": "25",
}
monsters = append(monsters, monster)
fmt.Println(monsters) //[map[age:18 name:Ronin] map[age:20 name:Tommy] map[age:25 name:Desire]]
|
map排序
- 先将map的key放入到切片中
- 对切片进行排序
- 遍历切片,然后按照key来输出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
| // map的排序
map1 := make(map[int]int, 10)
map1[10] = 100
map1[2] = 40
map1[5] = 1
map1[3] = 10
map1[9] = 20
// 打印结果,可以看到每次打印的结果顺序都不一样
for k, _ := range map1 {
fmt.Println(k)
}
// 如果按照map的key进行排序输出
// 1. 先将map的key放入到切片中
// 2. 对切片进行排序
// 3. 遍历切片,然后按照key来输出map的值
var keys []int
for k, _ := range map1 {
keys = append(keys, k)
}
fmt.Println(keys)
// 排序
sort.Ints(keys)
fmt.Println(keys)
for _, k := range keys {
fmt.Printf("map1[%v]=%v \n", k, map1[k])
}
|
map使用细节
- map是引用类型,遵守引用类型传递的机制,在一个函数接收map,修改后,会直接修改原来的map
- map的容量达到后,再想map增加元素,会自动扩容,并不会发生panic,也就是说map能动态的增长键值对
- map的value也经常使用struct类型,更适合管理复杂的数据