映射 (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
}

 

总结

最佳实践

  1. 函数设计

    • 保持函数简洁,单一职责

    • 合理使用多返回值处理错误

    • 谨慎使用可变参数

  2. 切片使用

    • 理解切片的底层数组共享机制

    • 注意切片扩容对性能的影响

    • 使用 copy() 避免意外修改

  3. Map 操作

    • 使用 comma ok 惯用法检查键是否存在

    • Map 不是线程安全的,并发访问需要同步

    • 零值 map 不能直接写入,需要先 make

  4. 结构体设计

    • 合理选择值接收者和指针接收者

    • 利用嵌入实现组合而非继承

    • 使用结构体标签进行序列化控制

这些数据结构和函数特性是 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)
}

映射的注意事项

  1. 映射是无序的

  2. 映射的零值是 nil

  3. 键必须是可比较的类型

  4. 映射是引用类型

实际应用示例

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