Go_map集合初始化、键值操作、map作为函数参数的使用
map:
- map是key-value的数据结构,又称为字典,像新华字典就是key:value类型展示的
- map是无序的,其中key是不允许重复的,key不存在相当于添加,存在相当于修改
- map的key必须支持相等运算,通常使用int、string,value,但slice、map、function不可以,因为不能用==、!=判断,引用类型不能作为key
- map必须先make才能使用,否则是一个空map且无法向该map添加数据
声明map:
格式1:
var map名称 map[key的类型]value的类型
格式2:
map名称 := map[key的类型]value的类型{}
格式3:
map名称 := make(map[key的类型]value的类型,size)
// map的大小是可以省略不写的,不写的时候会按照数据的大小自动分配
map声明后是不会分配内存的,比如数组创建完不管用不用内存都会开辟一块空间,但是map必须使用make关键字后才分配内存及使用,否则是一个空map且无法向该map添加数据
func main() {
var m1 map[int]string
m2 := map[int]string{}
m3 := make(map[int]string, 10)
fmt.Println("添加数据前m1:", m1, m1 == nil)
fmt.Println("添加数据前m2:", m2, m2 == nil)
fmt.Println("添加数据前m3:", m3, m3 == nil)
//m1[0] = "李白" // panic: assignment to entry in nil map
m2[0] = "韩信" // panic: assignment to entry in nil map
m3[0] = "露娜"
fmt.Println("添加数据后m2:", m2)
fmt.Println("添加数据后m3:", m3)
}ss
输出:
添加数据前m1: map[] true
添加数据前m2: map[] false
添加数据前m3: map[] false
添加数据后m2: map[0:韩信]
添加数据后m3: map[0:露娜]
map的初始化:
格式1:
var map名称 = map[key的类型]value的类型{key:value,key:value}
格式2:
map名称 := make(map[key的类型]value的类型)
map名称 [key] = value
如果key不存在就是添加,否则就是修改
func main() {
// 如果仅定义的,需要make后才能使用
var m1 map[string]string
m1 = make(map[string]string)
m1["打野"] = "露娜"
m1["中路"] = "不知火舞"
m1["中路"] = "干将莫邪"
fmt.Println("m1:", m1)
// 方式2
m2 := map[string]string{
"打野": "露娜",
"中路": "不知火舞",
"射手": "马可波罗",
}
fmt.Println("m2:", m2)
// 方式3
m3 := make(map[string]string)
m3["打野"] = "露娜"
m3["中路"] = "不知火舞"
m3["射手"] = "马可波罗"
fmt.Println("m3:", m3)
// 注意:因为key不能重复,如果都为空,也是相当于重复了
m4 := map[string]string{
"": "", // 报错:映射文字中的键 重复
"": "",
}
fmt.Println("m4", m4)
}
输出:
m1: map[中路:干将莫邪 打野:露娜]
m2: map[中路:不知火舞 射手:马可波罗 打野:露娜]
m3: map[中路:不知火舞 射手:马可波罗 打野:露娜]
map的value可以是另一个map
func main() {
// key是int
// value是一个map,这个map是的key和value都是string
m := make(map[int]map[string]string)
// 因为value也是一个map所以需要再make一下才可以赋值
m[0] = make(map[string]string)
m[0]["打野"] = "韩信"
m[1] = make(map[string]string)
m[1]["打野"] = "韩信"
fmt.Println(m)
}
输出:
map[0:map[打野:韩信] 1:map[打野:韩信]]
map键值操作:
格式 | 作用 |
---|---|
map名称[键] | 通过key获取值 |
v,ok := map[key] | 判断key是否存在,ok返回true则将key对应的value复制给v |
delete(map名称,键) | 通过key删除value,即使key不存在也不会报错 |
演示:
func main() {
m := map[string]string{"打野": "露娜", "中路": "不知火舞", "射手": "马可波罗"}
// 通过key获取value
fmt.Println(m["中路"])
// 直接删除key
fmt.Println("删除前:", m)
delete(m, "打野")
delete(m, "打野2") // 删除一个不存在key,不会报错
fmt.Println("删除后:", m)
// 判断key是否存在,key存在ok返回true
value, key := m["打野"]
if key {
fmt.Println(value)
} else {
fmt.Println("key不存在")
}
}
输出:
不知火舞
删除前: map[中路:不知火舞 射手:马可波罗 打野:露娜]
删除后: map[中路:不知火舞 射手:马可波罗]
key不存在
查找:
func main() {
m := map[string]string{"打野": "露娜", "中路": "不知火舞", "射手": "马可波罗"}
value, ok := m["打野"]
fmt.Println("直接输出:", value, ok)
// 判断后再输出
if ok {
fmt.Println("key", value, "存在")
} else {
fmt.Println("key", value, "不存在")
}
}
输出:
直接输出: 露娜 true
key 露娜 存在
统计map键值对个数
func main() {
m := map[string]string{"打野": "露娜", "中路": "不知火舞", "射手": "马可波罗"}
fmt.Println(len(m))
}
Map的遍历
func main() {
m := map[string]string{"打野": "露娜", "中路": "不知火舞", "射手": "马可波罗"}
for key, value := range m {
fmt.Println("key:", key, "value:", value)
}
}
map的value也是一个map,如何遍历
func main() {
m := make(map[int]map[string]string)
m[0] = make(map[string]string)
m[0]["打野"] = "韩信"
fmt.Println("直接打印m:", m)
// 外循环遍历的是外面的map
for key, value := range m {
fmt.Print("key:", key, "\n")
// 内循环遍历的是外面的map的value(value也是一个map,所以还要再遍历一次)
for v1, v2 := range value {
fmt.Println("value:", v1, v2)
}
}
}
输出:
直接打印m: map[0:map[打野:韩信]]
key:0
value: 打野 韩信
删除map
直接make一个新的map,让原来的成为垃圾,被GC回收
func main() {
m := map[string]string{"打野": "露娜", "中路": "不知火舞", "射手": "马可波罗"}
fmt.Println("重新make前:", m)
m = make(map[string]string)
fmt.Println("重新make后:", m)
}
输出:
重新make前: map[中路:不知火舞 射手:马可波罗 打野:露娜]
重新make后: map[]
或者使用遍历一个一个的删
func main() {
m := map[string]string{"打野": "露娜", "中路": "不知火舞", "射手": "马可波罗"}
fmt.Println("删除前:", m)
for key, _ := range m {
delete(m, key)
}
fmt.Println("删除后:", m)
}
输出:
删除前: map[中路:不知火舞 射手:马可波罗 打野:露娜]
删除后: map[]
map作为函数参数:
在函数中修改map的值,会影响到原来的map
func main() {
m := map[string]string{"打野": "露娜", "中路": "不知火舞", "射手": "马可波罗"}
mapDemo(m)
fmt.Println("修改后main中打印:", m)
}
func mapDemo(m map[string]string) {
fmt.Println("修改前:", m)
delete(m, "打野")
fmt.Println("修改后mapDemo中打印:", m)
}
输出:
修改前: map[中路:不知火舞 射手:马可波罗 打野:露娜]
修改后mapDemo中打印: map[中路:不知火舞 射手:马可波罗]
修改后main中打印: map[中路:不知火舞 射手:马可波罗]
map切片:
func main() {
// 声明并初始化切片
slice := make([]map[string]string, 2)
// 添加数据
slice[0] = make(map[string]string)
slice[0]["name"] = "韩信"
slice[0]["age"] = "99"
slice[1] = make(map[string]string)
slice[1]["name"] = "露娜"
slice[1]["age"] = "19"
fmt.Println(slice)
// 可以继续往里面添加数据
// 先创建一个map,再把map加到切片里
newMap := map[string]string{"name": "猴子", "age": "23"}
slice = append(slice, newMap)
fmt.Println(slice)
}
输出:
[map[age:99 name:韩信] map[age:19 name:露娜]]
[map[age:99 name:韩信] map[age:19 name:露娜] map[age:23 name:猴子]]
切片是有序的,可以把map的key放在切片然后通过切片取value完成排序,但还是比较麻烦
func main() {
TestMap := make(map[int]string)
TestMap[0] = "韩信"
TestMap[5] = "宫本"
TestMap[3] = "猴子"
TestMap[2] = "露娜"
TestMap[6] = "火舞"
TestMap[4] = "干将"
// 现在输出就是无序的
fmt.Println("排序前:", TestMap)
// 可以把map添加到切片中,切片就会按照key排序
var keys []int
for k, _ := range TestMap {
keys = append(keys, k)
}
// sort.Ints、sort.Strings等内置函数可以对切片排序
sort.Ints(keys)
fmt.Println("排序后:")
for _, k := range keys {
fmt.Print(k, TestMap[k], "\t")
}
}
输出:
排序前: map[0:韩信 2:露娜 3:猴子 4:干将 5:宫本 6:火舞]
排序后:
0韩信 2露娜 3猴子 4干将 5宫本 6火舞
将结构体作为value:
type Student struct {
name string
age int
}
func main() {
stu := make(map[string]Student)
stu1 := Student{"韩信", 18}
stu2 := Student{"李白", 78}
stu["001"] = stu1
stu["002"] = stu2
fmt.Println(stu)
}
输出:
map[001:{韩信 18} 002:{李白 78}]
统计字母出现的次数:
定义map,键盘录入的字母作为map的key,统计的次数作为map的value,循环遍历
func main() {
fmt.Println("请输入要统计的字母:")
// 定义统计次数的变量
var str string
fmt.Scan(&str)
m := make(map[byte]int)
for i := 0; i < len(str); i++ {
// 定义变量s作为map的key
s := str[i]
// 把S作为key,结果作为value,key如果重复,相当于修改
m[s] += 1
}
fmt.Println("统计的字符次数为:")
// 遍历
for key, value := range m {
fmt.Printf("%c:%d\n", key, value)
}
}
输出:
请输入要统计的字母:
itzhuzhu
统计的字符次数为:
i:1
t:1
z:2
h:2
u:2
版权声明:本文为weixin_45477086原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。