跳转到主要内容
模块 4 · 第 3 课(共 5)课程中的18/50~12 min
模块课程(3/5)

映射:键和值

map 是一个键→值哈希表:map[K]V。地图参考 types:传递给函数,它们共享相同的存储。他们一定是 在写入它们之前进行初始化(使用 make 或文字)。

创建

Go
// with a literal
prices := map[string]int{"pane": 2, "latte": 3}

// with make
counters := make(map[string]int)
counters["a"] = 1

// nil map (readable, NOT writable)
var m map[string]int
fmt.Println(m["x"])    // 0 — ok
// m["y"] = 1          // PANIC

基本操作

Go
m := map[string]int{"a": 1}

m["b"] = 2              // insert/update
v := m["a"]             // get; if missing: zero value
delete(m, "a")          // remove (ok even if the key doesn't exist)
n := len(m)             // number of entries

Comma-ok:区分“缺失”和“零值”

Go
v, ok := m["x"]
if !ok {
    fmt.Println("key missing")
} else {
    fmt.Println("found:", v)
}

这是知道键是否存在的唯一方法,因为 m["x"] 返回 即使密钥不存在,值也为零。一个基本模式。

迭代:随机顺序

Go
for k, v := range m {
    fmt.Println(k, v)
}

键:仅可比较的类型

键必须可比较:string、数字、bool、指针、 通道、接口、可比较类型的数组、可比较的结构 字段。 切片、贴图和函数不具有可比性 → 它们不能 成为钥匙。

Go
m := map[[2]int]string{}   // ok: array is comparable
// m := map[[]int]string{} // ERROR: slice is not comparable

图案: 柜台

地图最常见的用途之一:

Go
words := []string{"a", "b", "a", "c", "b", "a"}
freq := map[string]int{}
for _, w := range words {
    freq[w]++   // access to a missing key is 0 → 0+1 = 1
}
// freq = {"a": 3, "b": 2, "c": 1}

尝试一下

锻炼#go.m4.l3.e1
尝试:0加载中...

创建一个值为 'a' -> 1 和 'b' -> 2 的 map[string]int,然后添加 'c' -> 3。

正在加载编辑器...
显示提示

字面意思:`map[K]V{"key": value, ...}`。

3 次尝试后可用的解决方案

锻炼#go.m4.l3.e2
尝试:0加载中...

使用逗号-ok 模式将键“x”(不存在)读入 v, ok 并打印两者。

正在加载编辑器...
显示提示

两个返回值:值和存在布尔值。

3 次尝试后可用的解决方案

Quiz#go.m4.l3.e3
准备好

写入 nil 映射时会发生什么?

Go
var m map[string]int
m["a"] = 1
答案选项

回顾

  • map[K]V:键值、引用、哈希支持。
  • 使用 make 或文字进行初始化; nil 映射 → 写入时出现恐慌。
  • v, ok := m[k] 是区分“缺失”和“零值”的唯一方法。
  • delete(m, k) 删除;即使 k 不存在也可以。
  • range 迭代:随机顺序。
  • 键:仅可比较的类型(无切片/映射/函数)。
  • 计数器模式:freq[k]++ 利用隐式零值。