map的使用和细节

基本语法
var 变量名 map[key-type]value-type 例如 var a map[int]string->key是int类型,value是string类型。
注意:通常key为int,string类型,而slice,map和function不可以作为Key,因为这几个没法用==来判断。

func main() {
//map的声明 make的作用给map分配数据空间
var a map[string]string = make(map[string]string)
a["no1"] = "宋江"
a["no2"] = "吴用"
a["no1"] = "武松" //key不能重读,武松会覆盖松江
a["no3"] = "吴用"
fmt.Println(a) //map[no1:武松 no2:吴用 no3:吴用]
//数组在声明的时候已经分配数据空间了
var arr [5]int
arr[1] = 1
fmt.Println(arr) //[0 1 0 0 0]
}
  1. map使用前一定要make。
  2. map的key是不能重复的,如果重复了,则以最后这个key-value为准。
  3. map的value是可以相同的。
  4. map的key-value是无序的。
  5. make是一个内置函数,初始map的时候分配的创建取决于size。但产生的映射长度为0。size可以省略,这种情况下可以分配一个小的大小。

map的使用方式

func main() {
//方式1 声明后再分配空间
var a map[string]string
a = make(map[string]string, 10)
a["no1"] = "宋江"
a["no2"] = "吴用"
a["no1"] = "武松"
a["no3"] = "吴用"
fmt.Println(a) //map[no1:武松 no2:吴用 no3:吴用]
//方式2 类型判断直接make
cities := make(map[string]string)
cities["no1"] = "北京"
cities["no2"] = "天津"
cities["no3"] = "上海"
fmt.Println(cities) //map[no1:北京 no2:天津 no3:上海]
//方式3 初始化的时候就赋值
var heroes map[string]string = map[string]string{
"hero1": "猪猪侠",
"hero2": "钢铁侠",//这里结尾也要有逗号
}
fmt.Println(heroes) //map[hero1:猪猪侠 hero2:钢铁侠]
}

map的增删查改操作:

  • map的增加和更新:map["key"]=value //如果Key没有则增加,如果Key存在就是修改。
  • map的删除:delete(map,key),delete是一个内置函数,如果key存在,就删除key-value,如果Key不存在,不做任何变化,也不会报错。
func main() {
//定义个map
var a map[string]string
a = make(map[string]string, 10)
a["no1"] = "宋江"
a["no2"] = "吴用"
a["no1"] = "武松" //替换no1的value
a["no3"] = "吴用"
a["no3"] = "吴用1111" //替换no3的value
fmt.Println(a) //map[no1:武松 no2:吴用 no3:吴用1111]
//删除
delete(a, "no3")
fmt.Println(a) //map[no1:武松 no2:吴用]
}

说明:如果要清空整个map我们可以遍历整个map依次删除key。或者把map的指向一个新的空间,那么以前的Map空间会被GC回收。

  • map的查找: value,boole := map[key]
//引用上个代码块的map变量名是a
value, b := a["no1"]
if b {
fmt.Println("no1的值是", value)
} else {
fmt.Println("no1的值是空的")
}

map的遍历:

func main() {
//定义个map
var a map[string]string
a = make(map[string]string, 10)
a["no1"] = "宋江"
a["no2"] = "吴用"
a["no3"] = "吴用"
//遍历map只能用for range
for key, value := range a {
fmt.Println("key=", key, "value=", value)
}
//定义一个map
stus := make(map[string]map[string]string)
stus["no1"] = make(map[string]string, 3)
stus["no1"]["name"] = "张三"
stus["no1"]["sex"] = "男"
stus["no1"]["address"] = "北京长安街"
stus["no2"] = make(map[string]string, 3)
stus["no2"]["name"] = "小红"
stus["no2"]["sex"] = "女"
stus["no2"]["address"] = "上海红灯区"
for k1, v1 := range stus {
fmt.Println("k1=", k1)
for k2, v2 := range v1 {
fmt.Println("k2=", k2, "v2=", v2)
}
}
}

map切片
切片的数据类型如果是Map,那么这样的数据结构就是map切片,这样使用则map个数就可以动态变化的。

func main() {
//map切片 其实外层就是一个切片 里面的数据是map[string]string类型
monsters := make([]map[string]string, 2)
//增加数据
if monsters[0] == nil {
//切片的第一个元素是空的 那么就放入信息
monsters[0] = make(map[string]string)
monsters[0]["name"] = "牛魔王"
monsters[0]["age"] = "500岁"
}
if monsters[1] == nil {
monsters[1] = make(map[string]string)
monsters[1]["name"] = "玉兔精"
monsters[1]["age"] = "100岁"
}
//monsters切片分配了2个内存空间 如果要继续加元素需要append函数
monsters = append(monsters, map[string]string{
"name": "红孩儿",
"age": "200岁",
})
fmt.Println(monsters)//[map[age:500岁 name:牛魔王] map[age:100岁 name:玉兔精] map[age:200岁 name:红孩儿]]
}

map的排序

  1. golang中的map默认是无序的,也就是说不是按添加的顺序存放的,每次遍历,得到的输出可能不一样。
  2. 正对上面的问题,其实解决思路也很简单:定义一个切片存放map的key。 var keys = []int
    3 对切片进行排序,使用内置函数sort.Ints(keys),keys的定义的切片变量名字,类似是[]int
    4 遍历切片,根据key找到map中的value。
func main() {
//定义一个map
m := make(map[int]int)
m[10] = 100
m[1] = 13
m[4] = 56
m[8] = 90
fmt.Println(m)
//定义一个切片
var keys []int
//把map的key放入切片中
for k, _ := range m {
keys = append(keys, k)
}
//遍历切片按key输出map的value
for _, k := range keys {
fmt.Printf("%v:%v \n", k, m[k])
}
}

map细节

  1. map是引用类型,遵守引用传递的机制,在一个函数接收Map,修改后会直接修改原来的值。
  2. map可以动态增长容量。
  3. map的value也经常使用struct类型,更适合管理复杂的数据。
posted @   程序马2023  阅读(41)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 无需6万激活码!GitHub神秘组织3小时极速复刻Manus,手把手教你使用OpenManus搭建本
· C#/.NET/.NET Core优秀项目和框架2025年2月简报
· Manus爆火,是硬核还是营销?
· 终于写完轮子一部分:tcp代理 了,记录一下
· 【杭电多校比赛记录】2025“钉耙编程”中国大学生算法设计春季联赛(1)
点击右上角即可分享
微信分享提示