package main import "fmt" func main() { // 1. map[键类型]值类型:这里用姓名 string 查找成绩 int。 fmt.Println("=== 创建与查询 ===") scores := map[string]int{ "小朱": 90, "小李": 75, "小王": 0, } fmt.Printf("学生数量:%d\n", len(scores)) fmt.Printf("小朱的成绩:%d\n", scores["小朱"]) // 2. 新键是新增,已有键是修改;同一个 map 的键唯一。 fmt.Println("\n=== 新增与修改 ===") scores["小陈"] = 88 scores["小李"] = 80 fmt.Printf("新增小陈:%d,修改小李:%d\n", scores["小陈"], scores["小李"]) fmt.Printf("学生数量:%d\n", len(scores)) // 3. 读取不存在的键会得到值类型的零值,不会自动新增这个键。 // 仅凭 0 无法区分“成绩是 0”和“没有这个学生”,需要第二个返回值 ok。 fmt.Println("\n=== 判断键是否存在 ===") fmt.Printf("直接查询小赵:%d\n", scores["小赵"]) score, ok := scores["小王"] fmt.Printf("查询小王:成绩=%d,存在=%t\n", score, ok) score, ok = scores["小赵"] // 变量已声明,这里用 = 赋值。 fmt.Printf("查询小赵:成绩=%d,存在=%t\n", score, ok) // 也可以把查询放在 if 的初始化语句中。 // value 和 exists 只在这个 if / else 语句内有效。 if value, exists := scores["小李"]; exists { fmt.Printf("找到小李,成绩:%d\n", value) } else { fmt.Println("没有找到小李") } // 4. delete 删除键;删除不存在的键也不会报错。 fmt.Println("\n=== 删除 ===") delete(scores, "小王") delete(scores, "不存在的学生") _, ok = scores["小王"] fmt.Printf("删除后小王存在:%t,学生数量:%d\n", ok, len(scores)) // 5. range 遍历 map 的顺序不保证固定,不能依赖插入顺序。 // 这里只做求和,不按遍历顺序输出,因此结果稳定。 fmt.Println("\n=== 遍历与统计 ===") total := 0 for _, value := range scores { total += value } fmt.Printf("总分:%d\n", total) if len(scores) > 0 { average := float64(total) / float64(len(scores)) fmt.Printf("平均分:%.2f\n", average) } // 要固定显示顺序,可按一个明确的姓名切片逐项查询。 for _, name := range []string{"小朱", "小李", "小陈"} { fmt.Printf("%s:%d\n", name, scores[name]) } // 6. map 的零值是 nil:可以读取、查询、删除,但不能直接写入。 fmt.Println("\n=== nil 与 make ===") var tasks map[string]bool fmt.Printf("初始化前:nil=%t,长度=%d,读取结果=%t\n", tasks == nil, len(tasks), tasks["复习"]) // tasks["复习"] = true // 错误:向 nil map 写入会发生运行时 panic。 tasks = make(map[string]bool) tasks["复习"] = true fmt.Printf("初始化后:nil=%t,复习完成=%t\n", tasks == nil, tasks["复习"]) // 7. map 赋值不会复制所有元素,两个变量会指向同一份 map 数据。 fmt.Println("\n=== 赋值与共享 ===") alias := scores alias["小朱"] = 95 fmt.Printf("通过 alias 修改后,小朱的原成绩也变为:%d\n", scores["小朱"]) }