Map

map

是一种键值对数据结构,又称为字段或者关联数组,类似于其他编程语言中的集合。

声明

基本语法:

 // 方式一:直接声明 + make 初始化
 var myMap map[string]int
 myMap = make(map[string]int)
 ​
 // 方式二:直接 make(推荐)
 myMap := make(map[string]int)
 ​
 // 方式三:字面量方式(快速创建)
 myMap := map[string]int{
     "apple":  5,
     "banana": 3,
     "orange": 8,
 }

注意:

  1. var m map[int]string 只是声明了变量,但未分配内存!不能直接赋值,否则会 panic。
  2. 键(key)必须是可比较的类型(如:int, string, bool, struct 等),不能是 slice、map、function。
  3. key不可以重复,值可以重复,键值对是无序的
image-20251103214407654

使用

嵌套

map可以单个使用,也可以嵌套在一起使用,话不多说我们上案例,比如我现在存储学生的学号,姓名,性别

     //存储学生的学号,姓名,性别
  students := make(map[string]map[string]string)
  students["1001"] = map[string]string{
  "name": "威龙",
  "sex":  "男",
  }
  students["1002"] = map[string]string{
  "name": "麦晓雯",
  "sex":  "女",
  }
  students["1003"] = map[string]string{
  "name": "乌鲁鲁",
  "sex":  "男",
  }
  fmt.Println(students)
  fmt.Println(students["1003"]["name"])
 }
image-20251103215048399
CRUD 操作(Create, Read, Update, Delete)以及遍历

我们就用最经典最经典的学生信息管理系统来分析

     //存储学生的学号,姓名,性别
  students := make(map[string]map[string]string)
  students["1001"] = map[string]string{
  "name": "威龙",
  "sex":  "男",
  }
  students["1002"] = map[string]string{
  "name": "麦晓雯",
  "sex":  "女",
  }
  students["1003"] = map[string]string{
  "name": "乌鲁鲁",
  "sex":  "男",
  }
  fmt.Println(students)
  fmt.Println(students["1003"]["name"])
  //CURD操作
  //查询
  val, exists := students["1001"]
  if exists {
  fmt.Printf("学号1001的学生是:%s\n", val)
  } else {
  fmt.Println("未找到该学生")
  }
 ​
  //不安全的查询方式(会返回零值)
  fmt.Println("查询不存在的key:", students["999"])
 ​
  //更新
  students["1001"]["name"] = "红狼"
  fmt.Println("更新后:", students)
 ​
  //删除
  delete(students, "1002")
  fmt.Println("删除后:", students)
 ​
  // 遍历
  fmt.Println("\n最终所有学生:")
  for id, info := range students {
  fmt.Printf("学号: %s, 姓名: %s, 性别: %s\n", id, info["name"], info["sex"])
  }
image-20251103220728491

补充:

  1. 删除的时候如果找不到对应的key,不会有任何报错
  2. 如果我们要删除所有的key我们需要遍历key进行删除,或者用map = make(...),make一个新的让原来的成为垃圾,被gc回收
  3. map遍历只能用for-range

map切片

切片的数据类型如果是map,这样使用则map个数就可以动态变化了。

来个例子:使用map来记录工艺藏品的信息:id和quality,也就是说一个工艺藏品是一个map,并且妖怪的个数可以动态的增加。

既然可以动态增加,那我来写一个试试

     var craftedCollectibles []map[string]string
  craftedCollectibles = make([]map[string]string, 2)
  if craftedCollectibles[0] == nil {
  craftedCollectibles[0] = make(map[string]string, 2)
  craftedCollectibles[0]["id"] = "Heart of Africa"
  craftedCollectibles[0]["quality"] = "red"
  }
  if craftedCollectibles[1] == nil {
  craftedCollectibles[1] = make(map[string]string, 2)
  craftedCollectibles[1]["id"] = "Tears of the Ocean"
  craftedCollectibles[1]["quality"] = "red"
  }
  if craftedCollectibles[2] == nil {
  craftedCollectibles[2] = make(map[string]string, 2)
  craftedCollectibles[2]["id"] = "Tears of the Ocean"
  craftedCollectibles[2]["quality"] = "red"
  }
?

?怎么报错了???不是可以动态增加吗

那作为切片是不是要追加要通过一些手段?没错就是append函数

     craftedCollectibles = append(craftedCollectibles, map[string]string{
  "id":      "Tank model",
  "quality": "red",
  })

我们再来看看

image-20251104172138168

map排序

     a := map[int]string{
  3: "three",
  1: "one",
  2: "two",
  5: "five",
  4: "four",
  }
 ​
  var keys []int
  for k, _ := range a {
  keys = append(keys, k)
  }
  sort.Ints(keys)
  fmt.Println("按 key 升序输出:")
  for _, k := range keys {
  fmt.Printf("%d: %s\n", k, a[k])
  }

?不知道sort.Ints啥意思?自己点开看。

注意事项和细节

1.map是引用类型,遵守引用传递的机制,在一个函数接受了map,修改后会直接修改map的数值

2.map容量打倒后,再想map增加元素,会自动扩容,不会发生panic,map可以动态增长键值对

3.map的value也可以用结构体。

比如

 type User struct {
     Name  string
     Age   int
     Email string
 }
 ​
 func main() {
     users := make(map[string]User)
     users["alice"] = User{"Alice", 28, "alice@example.com"}
     users["bob"] = User{Name: "Bob", Age: 32}
     fmt.Println(users["alice"].Name)
 }

小案例:

要求:

  1. 使用map[string]map[string]sting 的map类型
  2.  key:表示用户名,是唯一的,不可以重复
  3. 如果某个用户名存在,就将其密码修改”888888”,如果不存在就增加这个用户信息,(包括昵称nickname和密码pwd)。
  4. 编写一个函数modifyUser(users map[string]map[string]sting,name string)完成上述功能
 package main
 ​
 import "fmt"
 ​
 func modifyUser(users map[string]map[string]string, name string) {
     if userMap, exists := users[name]; exists {
         userMap["pwd"] = "888888"
         fmt.Printf("用户 %s 已存在,密码已更新为 888888\n", name)
    } else {
         users[name] = map[string]string{
             "nickname": "default_user",
             "pwd":      "888888",
        }
         fmt.Printf("用户 %s 不存在,已新增\n", name)
    }
 }
 ​
 func main() {
     users := make(map[string]map[string]string)
     modifyUser(users, "alice")
     modifyUser(users, "bob")
     modifyUser(users, "alice")
     fmt.Println("\n最终用户数据:")
     for username, userInfo := range users {
         fmt.Printf("用户名: %s\n", username)
         fmt.Printf(" 昵称: %s\n", userInfo["nickname"])
         fmt.Printf(" 密码: %s\n", userInfo["pwd"])
         fmt.Println("---")
    }
 }
image-20251104173557535
暂无评论

发送评论 编辑评论


				
上一篇
下一篇