Go 语言 Map(集合)
在 Go 语言中,map 是一种内建的数据类型,它是无序的键值对集合,类似于其他编程语言中的字典(Python)或哈希表(Java)。map 可以通过键(key)来快速查找对应的值(value),它非常适合用于存储一对一的映射关系。
1. 声明和初始化 Map
1.1 使用 make 函数声明 Map
make 是 Go 内建的函数,可以用于初始化 map。
m := make(map[string]int) // 创建一个键为 string 类型,值为 int 类型的空 Map
1.2 使用字面量声明和初始化 Map
你还可以使用字面量的方式创建并初始化一个 map:
m := map[string]int{"apple": 5, "banana": 3, "cherry": 8}
2. 向 Map 中添加或修改元素
你可以通过键直接给 map 添加新元素或修改已有元素。
m := make(map[string]int)
m["apple"] = 5 // 添加键值对
m["banana"] = 3 // 添加键值对
// 修改现有元素
m["apple"] = 10 // 修改 "apple" 键的值
3. 从 Map 中删除元素
可以使用 delete 函数从 map 中删除指定键的元素。
m := map[string]int{"apple": 5, "banana": 3, "cherry": 8}
delete(m, "banana") // 删除键 "banana" 对应的元素
fmt.Println(m) // 输出: map[apple:5 cherry:8]
4. 查询 Map 中的元素
查询 map 时,如果键存在,它会返回对应的值。如果键不存在,它会返回该值类型的零值(如 0、"" 等)。为了避免值为零值时与键不存在的情况混淆,Go 提供了第二个返回值,用来判断键是否存在。
4.1 使用两值赋值法
m := map[string]int{"apple": 5, "banana": 3, "cherry": 8}
value, ok := m["apple"] // ok 为 true 表示键存在
fmt.Println(value, ok) // 输出: 5 true
value, ok = m["grape"] // ok 为 false 表示键不存在
fmt.Println(value, ok) // 输出: 0 false
5. 遍历 Map
可以使用 for range 循环遍历 map,返回每个键值对。
m := map[string]int{"apple": 5, "banana": 3, "cherry": 8}
for key, value := range m {
fmt.Println("Key:", key, "Value:", value)
}
输出:
Key: apple Value: 5
Key: banana Value: 3
Key: cherry Value: 8
- 请注意:
map中的遍历顺序是无序的,每次遍历的顺序可能不同。
6. 判断 Map 是否为 nil
未初始化的 map 是 nil,此时不能直接向其中添加元素。需要使用 make 函数来初始化 map。如果一个 map 为 nil,它的长度为 0,并且访问其中的元素会导致运行时错误。
6.1 示例:判断 Map 是否为 nil
var m map[string]int
fmt.Println(m == nil) // 输出: true
m = make(map[string]int)
fmt.Println(m == nil) // 输出: false
7. Map 的特点
- 无序性:
map中的键值对顺序是不确定的,每次遍历时,顺序可能会不同。 - 键的唯一性:
map中的键是唯一的,不能重复。如果插入相同的键,新值会覆盖旧值。 - 动态大小:
map可以动态增加或减少元素。 - 值的类型:
map的值可以是任何类型,包括其他的map。
8. Map 的内存和性能
- 内存:
map会根据其大小自动增长。初始容量较小,但随着元素增加,map会进行扩容。 - 性能:Go 的
map基于哈希表实现,提供了常数时间的查找、插入和删除操作(平均情况)。
9. 总结
- 声明:使用
make或字面量声明。 - 增删改查:通过键添加、删除、修改元素,并且使用两值赋值法判断键是否存在。
- 遍历:使用
range遍历map,顺序是无序的。 - nil 判断:未初始化的
map为nil,需要通过make函数初始化。