一、map 基本概念
-
定义 :Go 语言中的
map是键值对(key-value) 存储结构,也叫映射 -
核心特性
- 存储无序的键值对
- 键(key)必须是唯一的,重复赋值会覆盖旧值
- 只有
len()长度,没有 cap 容量 - 键的类型限制:函数、切片、map 不能作为 key(必须支持 == 比较)
-
语法格式
go
Go// 声明格式:map [键类型]值类型 var 变量名 map[keyType]valueType
二、map 的 3 种创建方式
1. 直接初始化(声明 + 赋值)
go
Go
// 键int类型,值string类型
info := map[int]string{
111: "mike",
110: "yoyo", // 最后一行逗号不能省略(Go语法要求)
}
2. 仅声明(未初始化,不能直接赋值)
go
Go
// 仅定义类型,未分配内存,值为nil
var m1 map[int]string
// 注意:直接赋值 m1[1] = "test" 会报错!
3. make 函数创建(推荐,分配内存)
go
Go
// 方式1:不指定长度
m2 := make(map[int]string)
// 方式2:指定初始长度(优化性能,底层仍可自动扩容)
m3 := make(map[int]string, 2)
三、map 常用操作
1. 赋值与追加
map 支持直接赋值,不存在的 key 会自动追加,底层自动扩容
go
Go
// 初始化map
m := map[int]string{1: "mike", 2: "yoyo"}
// 修改已有key的值
m[1] = "c++"
// 追加新key-value
m[3] = "go"
2. 遍历 map
使用for range遍历,结果无序,支持只遍历 key / 只遍历 value
go
Go
m := map[int]string{1: "mike", 2: "yoyo", 3: "go"}
// 遍历key和value
for key, value := range m {
fmt.Printf("%d ======》 %s\n", key, value)
}
// 只遍历key
for key := range m {
fmt.Println("key:", key)
}
// 只遍历value
for _, value := range m {
fmt.Println("value:", value)
}
3. 判断 key 是否存在
通过双返回值判断 key 是否存在,避免获取零值误判
go
Go
m := map[int]string{1: "mike"}
// value:key对应的值(不存在则为类型零值)
// ok:bool类型,true=key存在,false=key不存在
value, ok := m[0]
if ok {
fmt.Println("key存在,值为:", value)
} else {
fmt.Println("key不存在")
}
4. 删除元素
使用内置函数delete(map, key),删除不存在的 key不会报错
go
Go
m := map[int]string{1: "mike", 2: "yoyo"}
// 删除key=1的键值对
delete(m, 1)
// 删除不存在的key,无异常
delete(m, 100)
四、map 作为函数参数
map 是引用类型,函数内部修改 map(增删改),会影响外部原 map
go
Go
package main
import "fmt"
// map作为函数参数
func test(m map[int]string) {
delete(m, 1) // 函数内删除key
}
func main() {
m := map[int]string{1: "mike", 2: "yoyo"}
test(m)
fmt.Println(m) // 输出:map[2:yoyo],原map被修改
}
五、核心易错点总结
- 仅声明未用
make初始化的 map(nil map),不能直接赋值 - map 键必须唯一,重复赋值会覆盖旧值
- 遍历 map无序,不能依赖遍历顺序
- map 是引用类型,函数传参是传引用,会修改原数据
delete()函数删除不存在的 key,不会触发错误
总结
- map 是无序键值对,key 唯一、支持自动扩容,无容量限制
- 三种创建方式:直接初始化、仅声明、make 创建(推荐)
- 核心操作:赋值、遍历、判断 key 存在、delete 删除
- map 是引用类型,函数内修改会同步到外部原 map