2.6 【数据结构】Go 语言的映射(Map)
映射 (Map)
1. Map 基础操作
Map 声明和初始化
// 声明 map
var studentGrades map[string]int
// 使用 make 创建 map
studentGrades = make(map[string]int)
// Map 字面量
studentGrades = map[string]int{
"Alice": 95,
"Bob": 87,
"Charlie": 92,
}
// 简短声明
scores := map[string]int{
"Math": 90,
"English": 85,
}
Map 基本操作
func mapOperations() {
students := make(map[string]int)
// 添加/更新元素
students["Alice"] = 95
students["Bob"] = 87
// 获取元素
grade, exists := students["Alice"]
if exists {
fmt.Printf("Alice's grade: %d\n", grade)
}
// 删除元素
delete(students, "Bob")
// 遍历 map
for name, grade := range students {
fmt.Printf("%s: %d\n", name, grade)
}
// 获取长度
fmt.Printf("Number of students: %d\n", len(students))
}
2. Map 高级应用
嵌套 Map
type StudentInfo struct {
Age int
Grade int
}
func nestedMaps() {
// 嵌套 map
classRooms := map[string]map[string]StudentInfo{
"ClassA": {
"Alice": {Age: 20, Grade: 95},
"Bob": {Age: 21, Grade: 87},
},
"ClassB": {
"Charlie": {Age: 19, Grade: 92},
"David": {Age: 20, Grade: 88},
},
}
// 访问嵌套数据
aliceInfo := classRooms["ClassA"]["Alice"]
fmt.Printf("Alice: Age %d, Grade %d\n", aliceInfo.Age, aliceInfo.Grade)
}
Map 作为函数参数
func updateGrades(grades map[string]int, name string, newGrade int) {
grades[name] = newGrade // 直接修改原 map
}
func copyMap(original map[string]int) map[string]int {
copy := make(map[string]int)
for k, v := range original {
copy[k] = v
}
return copy
}
总结
最佳实践
函数设计
保持函数简洁,单一职责
合理使用多返回值处理错误
谨慎使用可变参数
切片使用
理解切片的底层数组共享机制
注意切片扩容对性能的影响
使用
copy()避免意外修改
Map 操作
使用 comma ok 惯用法检查键是否存在
Map 不是线程安全的,并发访问需要同步
零值 map 不能直接写入,需要先 make
结构体设计
合理选择值接收者和指针接收者
利用嵌入实现组合而非继承
使用结构体标签进行序列化控制
这些数据结构和函数特性是 Go 语言编程的基础,掌握它们对于编写高效、可维护的 Go 代码至关重要。
Go 基本数据结构
目录
映射 (Map)
什么是映射
映射是一种无序的键值对集合,类似于其他语言中的哈希表或字典。在 Go 中,映射是引用类型。
映射的声明和初始化
1. 声明映射
var m map[string]int // 声明一个映射,零值为 nil
m = make(map[string]int) // 使用 make 初始化
2. 直接初始化
m := map[string]int{
"apple": 5,
"banana": 3,
"orange": 8,
}
3. 使用 make 函数
m := make(map[string]int)
m["apple"] = 5
m["banana"] = 3
映射的基本操作
1. 添加和修改元素
m := make(map[string]int)
m["key1"] = 100 // 添加键值对
m["key1"] = 200 // 修改已存在的键
2. 访问元素
value := m["key1"] // 获取值
value, ok := m["key1"] // 获取值和存在标志
if ok {
fmt.Printf("key1 的值是: %d\n", value)
} else {
fmt.Println("key1 不存在")
}
3. 删除元素
delete(m, "key1") // 删除键值对
4. 遍历映射
m := map[string]int{"a": 1, "b": 2, "c": 3}
// 遍历键值对
for key, value := range m {
fmt.Printf("%s: %d\n", key, value)
}
// 只遍历键
for key := range m {
fmt.Printf("键: %s\n", key)
}
// 只遍历值
for _, value := range m {
fmt.Printf("值: %d\n", value)
}
映射的注意事项
映射是无序的
映射的零值是 nil
键必须是可比较的类型
映射是引用类型
实际应用示例
package main
import "fmt"
func main() {
// 学生成绩管理系统
students := map[string][]int{
"张三": {85, 92, 78},
"李四": {90, 88, 95},
"王五": {78, 82, 86},
}
// 计算每个学生的平均分
averages := make(map[string]float64)
for name, scores := range students {
total := 0
for _, score := range scores {
total += score
}
averages[name] = float64(total) / float64(len(scores))
}
// 输出结果
fmt.Println("学生平均分:")
for name, avg := range averages {
fmt.Printf("%s: %.2f\n", name, avg)
}
// 查找特定学生
if scores, exists := students["张三"]; exists {
fmt.Printf("张三的成绩: %v\n", scores)
}
}
作者:admin 创建时间:2025-09-21 19:06
最后编辑:admin 更新时间:2025-10-01 20:32
最后编辑:admin 更新时间:2025-10-01 20:32