map 是一种 key-value(键值对)数据结构:key(键)像姓名或编号,用来定位数据;value(值)是这个键对应的实际内容。你给 map 一个 key,它就帮你找到对应 value。
package main import "fmt" func main() { scores := make(map[string]int) scores["Tom"] = 90 v := scores["Tom"] fmt.Println(v) }
map[string]int 表示 key 的类型是 string(字符串),value 的类型是 int(整数)。类型写在这里,是为了限制这张 map 允许存什么数据。
| 语法 | 含义 |
|---|---|
make(map[string]int) | make 负责初始化,创建一张可写的 map |
m["Tom"] = 90 | 写入 / 更新 |
v := m["Tom"] | 读取;不存在时返回 value 类型的零值,也就是该类型的默认值,例如 int 的 0 |
v, ok := m["Tom"] | 读取并判断 key 是否存在 |
delete(m, "Tom") | 删除;key 不存在也安全 |
v, ok := m[key]。如果 value 是 int,m["Tom"] == 0 既可能表示 key 不存在,也可能表示 Tom 的值本来就是 0;此时 ok 才能把两种情况区分开。nil map
nil 表示这个 map 变量目前没有指向已经初始化的底层存储。它看起来像一个空 map,因此可以读,但还没有可写入的空间;强行写入会触发 panic,也就是程序发现无法继续执行当前操作时抛出的运行时错误。
var m map[string]int fmt.Println(m["a"]) // 0,可以读 m["a"] = 1 // panic: assignment to entry in nil map
key 为什么必须可比较
“可比较”是指两个值可以使用 == 判断是否相等。hash 只能帮你快速缩小范围,最终仍要判断“候选 key 和查询 key 是否真的相等”。所以 map key 必须可比较。slice(动态长度序列)、map 和 func(函数值)不能做 key;数组和结构体只有内部字段都可比较时才可以。