Golang入门教程10:数据映射艺术

72 阅读6分钟

在编程世界里,有一天,MapArray 决定一起去旅行。它们决定去一座叫做“内存”的城市。

Array 一直自豪地说:“我可是一个有序的家伙,我所有的元素都是按顺序排列的,访问我时只需要提供索引。”

Map 谦虚地回答:“嗯,我也是有序的,但我是通过键值对来组织的。而且,我是动态的,随时可以增加或删除元素。”

Array 看着 Map:“可是你的键值对太多了,你怎么知道哪一个是你要的?”

Map 微笑着:“哪有这么复杂,我只需要遍历一下就行啦,而且我的键是独一无二的,每一个都是特别的。”

于是,ArrayMap 一起踏上了旅途,虽然它们性格迥异,但却携手共进,让内存城市变得更加丰富多彩。

生活中的应用

map 数据结构的概念可以在生活中找到许多对应的例子,因为它模拟了一种键值对的关系。以下是一些生活中类似于 map 数据结构的应用:

  1. 地址簿: 想象一本地址簿,其中每个联系人的名字是键,而他们的地址是对应的值。通过名字(键),你可以迅速找到对应的地址(值)。

  2. 图书馆目录: 图书馆的书目目录可以被视为一个 map。书名是键,而实际书籍的详细信息(作者、出版日期等)是值。通过书名(键),你可以快速查找到相关的书籍信息(值)。

  3. 菜单: 餐厅的菜单可以看作是一个 map。菜名是键,而菜的价格和描述是值。通过菜名,你能够找到对应的价格和描述。

  4. 词典: 一本语言词典就是一个 map 的例子。每个单词是键,而其对应的含义是值。通过查询单词,你能够找到它的含义。

  5. 物流追踪系统: 物流公司使用 map 类似的结构来追踪货物。货物的编号是键,而货物的当前位置、状态等信息是值。

  6. 电子商务购物车: 购物车可以被视为一个 map,商品ID是键,而购物车中每个商品的数量是值。通过商品ID,你可以获取到购物车中每个商品的数量。

  7. 学生成绩记录: 一份学生成绩记录可以被看作一个 map。学生的学号是键,而他们的成绩是值。通过学号,你可以查找到每个学生对应的成绩。

这些例子展示了在日常生活中 map 数据结构的类比,说明了它是一种非常实用的方式,用于表示和组织键值对关系的数据。

Golang中Map的概念

在Go语言中,map 是一种用于存储键值对的集合。它提供了一种高效的方式来查找、插入和删除数据。以下是map的核心概念:

  1. 定义:

    var m map[keyType]valueType
    

    map 的定义需要指定键的类型 (keyType) 和值的类型 (valueType)。例如,map[string]int 表示键是字符串类型,值是整数类型。

  2. 初始化:

    m := make(map[keyType]valueType)
    

    使用 make 函数初始化一个空的 map。这个时候,m 是一个空的映射,可以用来存储键值对。

  3. 插入与更新:

    m[key] = value
    

    可以通过键直接对 map 进行插入或更新操作。如果键已存在,对应的值将被更新;如果键不存在,则新的键值对将被添加。

  4. 删除元素:

    delete(m, key)
    

    使用 delete 函数可以删除 map 中指定键的键值对。

  5. 查找元素:

    value, exists := m[key]
    

    使用键来查找对应的值。如果键存在,exists 的值为 truevalue 包含对应的值;如果键不存在,exists 的值为 falsevalue 包含值类型的零值。

  6. 迭代:

    for key, value := range m {
        // 在这里处理每对键值对
    }
    

    使用 range 关键字可以迭代 map 中的所有键值对。在循环中,key 是键,value 是对应的值。

map 是一种动态的数据结构,它会根据存储的键值对动态地调整大小。在使用 map 时,需要注意以下几点:

  • map 是引用类型,可以直接赋值给其他 map 变量,并且它们会共享相同的底层数组。
  • map 的键必须是支持相等运算符的类型,例如整数、浮点数、字符串、指针、数组、结构体等。而值可以是任意类型。
  • 对一个不存在的键取值会返回值类型的零值,因此需要通过第五点中的方式来判断键是否存在。

总体而言,map 是Go语言中非常常用和灵活的数据结构,适用于快速的键值对查找和存储。

实践代码讲解

这段Go代码演示了map的基本操作和一些相关函数的使用。以下是对代码的解释:

  1. 创建和插入键值对:

    m := make(map[string]int)
    m["k1"] = 7
    m["k2"] = 13
    

    使用 make 创建了一个新的空map,然后插入了两个键值对,分别是 "k1" 对应 7,"k2" 对应 13。

  2. 打印map内容:

    fmt.Println("map:", m)
    

    使用 Println 打印整个 map 的内容。

  3. 通过键取值:

    v1 := m["k1"]
    fmt.Println("v1: ", v1)
    

    通过键 "k1" 取值,打印出对应的值。

  4. 不存在的键取值:

    v3 := m["k3"]
    fmt.Println("v3: ", v3)
    

    尝试获取一个不存在的键 "k3" 的值,由于该键不存在,打印出值类型的零值。

  5. 获取map长度:

    fmt.Println("len:", len(m))
    

    使用 len 函数获取 map 的键值对数量。

  6. 删除键值对:

    delete(m, "k2")
    fmt.Println("map:", m)
    

    使用 delete 函数删除键为 "k2" 的键值对。

  7. 检查键是否存在:

    _, prs := m["k2"]
    fmt.Println("prs:", prs)
    

    使用 _ 忽略掉不需要的值,然后通过 prs 变量检查键 "k2" 是否存在。

  8. 使用字面量创建map

    n := map[string]int{"foo": 1, "bar": 2}
    fmt.Println("map:", n)
    

    使用字面量方式创建了一个包含两个键值对的 map

  9. 比较两个map是否相等:

    n2 := map[string]int{"foo": 1, "bar": 2}
    if maps.Equal(n, n2) {
        fmt.Println("n == n2")
    }
    

    使用 maps.Equal 函数比较两个 map 是否相等,如果相等则输出相等的消息。

这个例子涵盖了map的基本操作,包括创建、插入、删除、获取值等操作。

实践代码

package main

import (
   "fmt"
   "golang.org/x/exp/maps"
)

func main() {
   m := make(map[string]int)

   m["k1"] = 7
   m["k2"] = 13

   fmt.Println("map:", m)

   v1 := m["k1"]
   fmt.Println("v1: ", v1)

   v3 := m["k3"]
   fmt.Println("v3: ", v3)

   fmt.Println("len:", len(m))

   delete(m, "k2")
   fmt.Println("map:", m)

   _, prs := m["k2"]
   fmt.Println("prs:", prs)

   n := map[string]int{"foo": 1, "bar": 2}
   fmt.Println("map:", n)

   n2 := map[string]int{"foo": 1, "bar": 2}
   if maps.Equal(n, n2) {
      fmt.Println("n == n2")
   }
}