Fork me on GitHub

Golang之旅33-map映射

map 映射

基本介绍

  • map是无序的
  • key-value组成
  • make初始化之后才能够使用
  • map是引用类型的,遵守引用类型传递的机制
1
2
3
4
5
6
var mapName map[keytype]valuetype

var a map[string]string
var b map[string]int
var c map[int]string
var d map[string]map[string]string // value是map类型
  1. 可以当作key的值类型:
  • bool布尔值
  • int数字(通常)
  • string字符串(通常)
  • pointer指针
  • channel通道
  1. 可以当作value的值类型
  • bool布尔值
  • 数字(通常)
  • string字符串(通常)
  • pointer指针
  • channel通道

通常是数字,string,map,struct


初始化make

map的声明是不会分配内存的,需要进行make初始化后才会分配内存。

  • key不能重复,无序的
  • value可以重复
1
2
3
4
5
6
var a map[string]string
a = make(map[string]string,10) // make的作用是给map分配数据空间
a["p1"] = "miaoxing"
a["p2"] = "xiaohong"
a["p3"] = "miaoxing" // 覆盖上面
a["p4"] = "xiaohong" // 出现来个xiaohong

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
package main
import "fmt"
func main(){
// 方式1
var a map[string]string
a = make(map[string]string,10) // make的作用是给map分配数据空间
a["p1"] = "miaoxing"
a["p2"] = "xiaohong"
a["p3"] = "miaoxing" // 覆盖上面
a["p4"] = "xiaohong" // 出现来个xiaohong
fmt.Println(a)

// 方式2(推荐)
cities := make(map[string]string)
cities["p1"] = "北京"
cities["p2"] = "上海"
cities["p3"] = "深圳"
fmt.Println(cities)

// 方式3
heroes := map[string]string{
"hero1":"宋江",
"hero2":"卢俊义",
}
heroes["hero3"] = "林冲"
fmt.Println(heros)
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
// 案例
package main
import "fmt"

// 定义一个map用来存放学生的信息,每个学生有name和sex信息

func main(){
studentMap := make(map[string]map[string]string) // 初始化整个map

studentMap["stu01"] = make([string]string, 3) // 整个map的值也是个map,需要进行初始化;3表示三个信息
studentMap["stu01"]["name"] = "Tom"
studentMap["stu01"]["sex"] = "男"
studentMap["stu01"]["address"] = "深圳"

studentMap["stu02"] = make([string]string, 3) // 整个map的值也是个map,需要进行初始化;3表示三个信息
studentMap["stu01"]["name"] = "Jackson"
studentMap["stu01"]["sex"] = "男"
studentMap["stu01"]["address"] = "广州"
}

map 之增删改查crud

  • key不存在就是增加,存在就是修改;
  • 删除delete(map, “key”):内置函数,k-v存在则删除;不存在,不操作,也不会报错
  • 如果要删除全部key-value:需要遍历全部的key;或者通过make(...)形成一个新的map,原来的通过gc回收
  • 查找key-value
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
package main
import "fmt"
func main(){
// 声明并初始化
cities := make(map[string]string)
cities["p1"] = "北京"
cities["p2"] = "上海"
cities["p3"] = "深圳"
fmt.Println(cities)

// map的查找
val,ok. := cities["p1"]
if ok {
fmt.Println("存在p1,值为%v\n", val)
} else{
fmt.Println("没有p1 key\n")
}
}

map遍历

只能通过for-range来进行遍历

1
2
3
4
5
6
7
8
9
10
11
12
package main
import "fmt"

func main(){
cities := make(map[string]string)
cities["p1"] = "北京"
cities["p2"] = "上海"
cities["p3"] = "深圳"
for k, v := range cities{
fmt.Printf("k=%v v=%v", k,v)
}
}

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
26
27
28
29
package main
import "fmt"

func main(){
// 1. map类型的切片
var monsters []map[string]string
monsters = make([]map[string]string, 2) // 对切片的初始化,准备放入两个2个monsters信息
// 2. 增加一个monster的信息
if monsters[0] == nil{ // 如果消息是空的,则通过map存入数据
monsters[0] = make(map[string]string, 2) // map的初始化
monsters[0]["name"] = "牛魔王"
monsters[0]["age"] = "500" // value的类型是string,必须使用字符串
}

if monsters[1] == nil{
monsters[1] = make(map[string]string, 2) // map的初始化
monsters[1]["name"] = "玉兔精"
monsters[1]["age"] = "400" // value的类型是string,必须使用字符串
}

// 使用append动态增加monster
// 1. 先定义一个monster信息
newMonster := map[string]string{
"name": "新妖怪-白骨精",
"age": "200",
}
monsters = append(monsters, newMonster) // append使用
fmt.Println(monsters)
}

map排序

  • 默认是无序,也不是按照添加的顺序排序的
  • golang中的map排序,是现将key进行排序,然后根据key遍历输出即可
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
29
30
31
32
33
package main
import (
"fmt"
"sort"
)

func main(){
map1 := make(map[int]int, 10)
map1[0] = 3
map1[9] = 9
map1[3] = 8
map1[1] = 6
map1[8] = 7

// map排序
// 1. 现将map中的key放入切片中
// 2. 对切片进行排序
// 3. 遍历切片,然后按照key来输出map的值

var keys []int // 定义切片,将key放入切片中
for k, v := range map1{
keys = append(keys,v)
}

// sort排序
sort.Ints(keys) // 对keys进行排序
fmt.Println(keys)

// 遍历切片
for _, k := range keys{ // 对keys进行遍历获取k
fmt.Printf("map1[%v]=%v \n", k, map1[k]) // 输出k及对应的value值
}
}

使用细节

  • 引用类型
  • map容量达到后,会增加map元素,实现动态扩容,不会发生panic
  • mapvalue经常使用结构体struct;更适合管理复杂的数据
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
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
package main
import "fmt"

func modify(map1 map[int]int){
map1[10] = 900
}

// 定义一个学生结构体
type Stu struct{
Name string
Age int
Address string
}

func main(){
// 引用类型
// 修改后会改变原来的值
map1 := make(map[int]int, 3) // 容量是3,下面的key达到了20,动态扩容
map1[1] = 90
map1[2] = 88
map1[10] = 3
map1[20] = 4
modify(map1)
fmt.Println(map1) // 结果:map1[10] = 900

// 结构体存储 map 的信息
students := make(map[string]Stu, 10) // value 是 Stu 类型
stu1 := Stu{"Name": "tom", "Age": 18, "Address": "深圳"}
stu2 := Stu{"mary", 25, "上海"}

students["p1"] = stu1
students["p2"] = stu2
fmt.Println(students)

// 遍历学生信息
for k,v := range students{ // v就是Stu的实例,通过实例获取属性
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的值同样是map类型,需要进行两次的make初始化操作。

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
29
30
31
32
package main
import "fmt"

/*
1. map[string]map[string]string
*/

func modifyUser(users map[string]mapp[string]string, name string){
// 判断user中是否有name
// v, ok := users[name]
if users[name] != nil{
// 不是空的,说明用户存在,直接修改密码
users[name]['pwd'] = '888888'
} else {
users[name] = make(map[string]string, 2) // 存放昵称和密码
users[name]['pwd'] = '888888'
users[name]['nickname'] = "昵称~" + name
}
}

func main(){
users := make(map[string]map[string]string, 10) // key是string类型,value是切片类型 map[string]string
users["smith"] = make(map[string]string, 2)
users["smith"]["pwd"] = "999999"
users["smith"]["nickname"] = "小花猫"

modifyUser(users, "tom")
modifyUser(users, "mary")
modidyUser(users, "smith") // 用户存在,仅仅修改密码

fmt.Println(users)
}

本文标题:Golang之旅33-map映射

发布时间:2019年11月14日 - 00:11

原始链接:http://www.renpeter.cn/2019/11/14/Golang%E4%B9%8B%E6%97%8533-map%E6%98%A0%E5%B0%84.html

许可协议: 署名-非商业性使用-禁止演绎 4.0 国际 转载请保留原文链接及作者。

Coffee or Tea