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
  • 1
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

itzhuzhu.

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值