基本介绍
Map 是一种无序的键值对的集合。
基本使用
初始化
初始化 Map 可以使用 make 函数,也可以使用字面量的方式直接初始化值。
// 创建一个空的 Mapm1 := make(map[string]int)// 使用字面量的方式m2 := map[string]int{"apple": 1,"banana": 2,"orange": 3,}fmt.Println(m1) // map[]fmt.Println(m2) // map[apple:1 banana:2 orange:3]
设置元素
使用 Map 名加键名的方式,可以设置一个键值对,如果有值则修改,没有则新建一个键值对。
// 修改原有的值m2["apple"] = 4fmt.Println(m2) // map[apple:4 banana:2 orange:3]// 设置新的值m2["apple2"] = 5fmt.Println(m2)// map[apple:4 apple2:5 banana:2 orange:3]
获取值
通过键名获取 Map 相对应的键值,获取键值的同时也可以获取键是否存在。
// 直接获取键值value := m2["apple"]fmt.Println(value) // 4// 获取键值,并获取是否存在value1,ok1 := m2["apple"]fmt.Println(ok1) // truefmt.Println(value1) // 4// 获取键值,并获取是否存在value2,ok2 := m2["apple3"]fmt.Println(ok2) // falsefmt.Println(value2) // 0
获取 Map 元素数量
可以通过 len 函数获取 Map 元素的数量
m3 := map[string]int{"apple": 1,"banana": 2,"orange": 3,"apple1": 3,"apple2": 3,"apple3": 3,}fmt.Println(len(m3)) //6
删除元素
- go 提供了一个用来删除 Map 元素的函数,delete 函数,传递 Map 和需要删除的键名。
- go 没有提供清空整个 Map 的方法,需要清空可以将 nil 赋值给 Map
delete(m3,"apple1")delete(m3,"apple2")delete(m3,"apple3")fmt.Println(m3)// map[apple:1 banana:2 orange:3]// 清空mapm3 = nilfmt.Println(m3) // map[]
遍历 Map
- 遍历 map 可以使用 for range 语法来遍历 Map
- 不过 map 是无序的,不能保证输出顺序是固定的
for k,v := range m3{fmt.Printf("Key:%s Result:%d\n",k,v)}
引用类型
map 和切片一样也是引用类型,如果直接用 = 赋值,两者其实指向的 map 是一样的
m4 := m3fmt.Println(m4) // map[apple:1 banana:2 orange:3]m3["apple"] = 10fmt.Println(m3) // map[apple:10 banana:2 orange:3]fmt.Println(m4) // map[apple:10 banana:2 orange:3]
可以看到把 m3 赋值给 m4 之后,修改了 m3 的某个key ,m4 也一起改动了
注意事项
- Map 是引用类型,注意赋值或者传参给函数的时候实际都是相同的 Map。
- Map 的键必须是可比较的类型,如整数、字符串和指针等,但是切片、函数和结构体等类型是不可比较的,因此不能用作键。
- Map 中的元素是无序的,这意味着遍历 Map 时,元素的顺序可能会随机改变。
- Map 的容量是动态变化的,它会自动调整容量以适应新的元素。
- 如果使用未初始化的 Map,会导致运行时错误。需要使用 make() 函数来初始化 Map。
- Map 在并发环境下不是安全的。如果需要在并发环境下使用 Map,需要使用 sync 包中提供的锁机制来保护 Map。
- Map 并发读写会造成致命错误,所以在并发环境中要想清楚使用 Map 的场景,和加锁的地方。