【GO语言卵细胞级别教程】10.探索Go语言中神奇的Map类型:解密键值对的魔力(含习题)
🥰微信公众号:【给点知识】分享小知识,快速成长,欢迎关注呀!(底部点击二维码)
🥰本项目演示代码仓库:https://gitee.com/gdzsfun/csdn-study-go 演示项目仓库
🥰本项目创建方式:【GO语言卵细胞级别教程】05.项目创建和函数讲解
🥰学习宗旨:活到老,学到老。
😍写作宗旨:致力于改变现有文章难读难懂问题。
1.简介
map就是类似python中的字典,是一对键值对key-value。
例如:
学生1:学号1
学生2:学号2
{
"name":"张三",
"age":"19"
}
- 注意事项
(1)key value的类型 bool 数组 指针 channel、结构体、接口、数组
(2)key通常是为int string value通常为 map int float string 结构体
(3)key 不能为 slice map function
(4)map排序是乱序的
(5)使用之前一定要使用make申请空间
(6)key不能重复,后面的会把前面已经赋值的给覆盖了
(7)使用make(map, size)初始的时候,size可以省略默认为1
2. 基本语法
- 定义映射类型使用make(map, size)
// 语法
var mapName map[keyType]valueType
// 举例
var map1 map[int]string
map1 = make(map[int]string)
// 例子
var a map[int]string
a = make(map[int]string, 1)
a[100] = "中国"
a[99] = "美国"
a[98] = "印度"
fmt.Println(a)
// 输出结果
map[98:印度 99:美国 100:中国]
- makei不加长度make(map)
var map2 map[int]string
map2 = make(map[int]string)
// 或者
map2 := make(map[int]string)
map2[100] = "中国"
- 直接赋值
// 使用显示定义
var map2 map[int]string = map[int]string{
123:"123",
}
fmt.Println(map2)
// 使用隐式定义
map3 := map[int]string{
345:"345",
}
fmt.Println(map3)
// 输出结果
map[123:123]
-----
map[345:345]
- 多级映射
var selfInfoMap map[string]map[string]string
selfInfoMap = make(map[string]map[string]string)
selfInfoMap["student1"] = make(map[string]string)
selfInfoMap["student1"]["name"] = "张三"
selfInfoMap["student1"]["age"] = "19"
selfInfoMap["student1"]["notes"] = "优秀"
实战
var selfInfoMap map[string]map[string]string
selfInfoMap = make(map[string]map[string]string)
selfInfoMap["student1"] = make(map[string]string)
selfInfoMap["student1"]["name"] = "张三"
selfInfoMap["student1"]["age"] = "19"
selfInfoMap["student1"]["notes"] = "优秀"
for _,v := range selfInfoMap{
fmt.Printf("学生:%v, 年龄:%v, 备注:%v\n",
v["name"],
v["age"],
v["notes"])
}
//输出结果
学生:张三, 年龄:19, 备注:优秀
3.Map基本操作
3.1 增删改查
- 增加与更新操作
只用使用mapx[key] = value
(1)如果key存在则更新,反之增加元素
package mystudy
// 映射map知识点
import "fmt"
func DemoMap(){
// map基本操作
fmt.Println("------map基本操作------")
map6 := make(map[int]string)
map6[1] = "111"
map6[2] = "222"
fmt.Println(map6)
// 增加操作
map6[3] = "333"
fmt.Println("新增key:3 value", map6[3])
// 更新操作
map6[3] = "3-3-3"
fmt.Println("修改key:3 value", map6[3])
}
// 输出结果
------map基本操作------
map[1:111 2:222]
新增key:3 value 333
修改key:3 value 3-3-3
- 删除操作:delete(map, “key”)
package mystudy
// 映射map知识点
import "fmt"
func DemoMap(){
// map基本操作
fmt.Println("------map基本操作------")
map6 := make(map[int]string)
map6[1] = "111"
map6[2] = "222"
fmt.Println(map6)
map6[3] = "333"
fmt.Println("新增key:3 value", map6[3])
map6[3] = "3-3-3"
fmt.Println("修改key:3 value", map6[3])
// 删除操作
fmt.Println("删除前map6:", map6)
delete(map6,3)
fmt.Println("删除后map6:", map6)
}
// 输出结果
删除前map6: map[1:111 2:222 3:3-3-3]
删除后map6: map[1:111 2:222]
- 清空数组操作
1. 清空操作,方式1使用delete遍历删除
2. 使用make赋值新的空间
map6 = make(map[int]string)
- 获取值操作map6[2] 会有两个返回值,一个是value 一个是元素是否存在的布尔类型
true 存在,false 不存在 value对应的类型以及默认值就是 map[int]string 值对应的类型,比如
map[int]string 值类型是string那么这个字符串就是空的 如果是 map[int]int 那么如果获取不到就默认是0 false
package mystudy
// 映射map知识点
import "fmt"
func DemoMap(){
// map基本操作
fmt.Println("------map基本操作------")
map6 := make(map[int]int)
map6[1] = 111
map6[2] = 222
fmt.Println(map6)
// 增加操作
map6[3] = 333
fmt.Println("新增key:3 value", map6[3])
// 更新操作
map6[3] = 33333
fmt.Println("修改key:3 value", map6[3])
// 删除操作
fmt.Println("删除前map6:", map6)
delete(map6,3)
fmt.Println("删除后map6:", map6)
// 清空map6
// map6 = make(map[int]string)
// fmt.Println(map6)
// 获取值操作
value, bool1:= map6[2]
fmt.Printf("%T, %T\n", value, bool1)
fmt.Println(value, bool1)
value, bool1 = map6[22]
fmt.Printf("%T, %T\n", value, bool1)
fmt.Println(value, bool1)
}
// 输出结果
------map基本操作------
map[1:111 2:222]
新增key:3 value 333
修改key:3 value 33333
删除前map6: map[1:111 2:222 3:33333]
删除后map6: map[1:111 2:222]
int, bool
222 true
int, bool
0 false
3.2 遍历
- 使用for - range进行遍历
package mystudy
// 映射map知识点
import "fmt"
func DemoMap(){
// 定义多级映射
var selfInfoMap map[string]map[string]string
selfInfoMap = make(map[string]map[string]string)
selfInfoMap["student1"] = make(map[string]string)
selfInfoMap["student1"]["name"] = "张三"
selfInfoMap["student1"]["age"] = "19"
selfInfoMap["student1"]["notes"] = "优秀"
for _,v := range selfInfoMap{
fmt.Printf("学生:%v, 年龄:%v, 备注:%v\n",
v["name"],
v["age"],
v["notes"])
}
}
// main
学生:张三, 年龄:19, 备注:优秀
- 获取map长度,使用len(xxx)
4. 本章的代码
package mystudy
// 映射map知识点
import "fmt"
func DemoMap(){
// 定义map变量
var a map[int]string
a = make(map[int]string, 1)
a[100] = "中国"
a[99] = "美国"
a[98] = "印度"
fmt.Println(a)
fmt.Println("-----")
var map1 map[int]string
map1 = make(map[int]string)
map1[66] = "以色列"
map1[68] = "巴勒斯坦"
fmt.Println(map1)
fmt.Println("------")
var map2 map[int]string = map[int]string{
123:"123",
}
fmt.Println(map2)
fmt.Println("-----")
map3 := map[int]string{
345:"345",
}
fmt.Println(map3)
fmt.Println("-----")
// 定义多级映射
var selfInfoMap map[string]map[string]string
selfInfoMap = make(map[string]map[string]string)
selfInfoMap["student1"] = make(map[string]string)
selfInfoMap["student1"]["name"] = "张三"
selfInfoMap["student1"]["age"] = "19"
selfInfoMap["student1"]["notes"] = "优秀"
for _,v := range selfInfoMap{
fmt.Printf("学生:%v, 年龄:%v, 备注:%v\n",
v["name"],
v["age"],
v["notes"])
}
// 获取长度
fmt.Println(len(selfInfoMap))
// map基本操作
fmt.Println("------map基本操作------")
map6 := make(map[int]int)
map6[1] = 111
map6[2] = 222
fmt.Println(map6)
// 增加操作
map6[3] = 333
fmt.Println("新增key:3 value", map6[3])
// 更新操作
map6[3] = 33333
fmt.Println("修改key:3 value", map6[3])
// 删除操作
fmt.Println("删除前map6:", map6)
delete(map6,3)
fmt.Println("删除后map6:", map6)
// 清空map6
// map6 = make(map[int]string)
// fmt.Println(map6)
// 获取值操作
value, bool1:= map6[2]
fmt.Printf("%T, %T\n", value, bool1)
fmt.Println(value, bool1)
value, bool1 = map6[22]
fmt.Printf("%T, %T\n", value, bool1)
fmt.Println(value, bool1)
}
- 多嵌套遍历
package main
import "fmt"
func main() {
// 创建多个嵌套的映射
employeeMap := make(map[string]map[string]string)
// 添加数据到映射中
employeeMap["John"] = map[string]string{
"position": "Manager",
"department": "Sales",
"city": "New York",
}
employeeMap["Alice"] = map[string]string{
"position": "Engineer",
"department": "IT",
"city": "San Francisco",
}
employeeMap["Bob"] = map[string]string{
"position": "Analyst",
"department": "Finance",
"city": "Chicago",
}
// 遍历多个嵌套的映射
for name, details := range employeeMap {
fmt.Printf("Employee: %s\n", name)
fmt.Println("Details:")
for key, value := range details {
fmt.Printf("%s: %s\n", key, value)
}
fmt.Println()
}
}
5.练习题
当提供一些Go语言的映射(Map)练习题,包括选择题和算法题。以下是几个例子及其答案:
选择题:
-
下面哪个选项是创建一个空映射的正确方式?
a)var m map[string]int
b)m := make(map[string]int)
c)m := map[string]int{}
d)m := new(map[string]int)
答案:b)
m := make(map[string]int)
-
假设有一个映射
m
,如何判断键"key1"
是否存在于映射中?
a)if m["key1"] != nil
b)if _, ok := m["key1"]; ok
c)if m["key1"] != ""
d)if _, ok := m["key1"]
答案:b)
if _, ok := m["key1"]; ok
算法题:
- 给定一个字符串,统计每个字符出现的次数,并将结果存储在一个映射中。
func countCharacters(str string) map[rune]int {
charCount := make(map[rune]int)
for _, char := range str {
charCount[char]++
}
return charCount
}
func main() {
str := "abracadabra"
result := countCharacters(str)
fmt.Println(result)
}
输出结果:
map[a:4 b:2 r:2 c:1 d:1]
- 给定两个映射
m1
和m2
,编写一个函数判断它们是否相等,即包含相同的键和对应的值。
func mapsEqual(m1, m2 map[string]int) bool {
if len(m1) != len(m2) {
return false
}
for key, val := range m1 {
if m2Val, ok := m2[key]; !ok || m2Val != val {
return false
}
}
return true
}
func main() {
m1 := map[string]int{"a": 1, "b": 2, "c": 3}
m2 := map[string]int{"a": 1, "b": 2, "c": 3}
fmt.Println(mapsEqual(m1, m2)) // true
m3 := map[string]int{"a": 1, "b": 2, "c": 3}
m4 := map[string]int{"a": 1, "b": 3, "c": 3}
fmt.Println(mapsEqual(m3, m4)) // false
}
输出结果:
true
false