100天精通Golang(基础入门篇)——第12天:深入解析Go语言中的集合(Map)及常用函数应用

简介: 100天精通Golang(基础入门篇)——第12天:深入解析Go语言中的集合(Map)及常用函数应用

🌷 博主 libin9iOak带您 Go to Golang Language.✨

🦄 个人主页——libin9iOak的博客🎐
🐳 《面试题大全》 文章图文并茂🦕生动形象🦖简单易学!欢迎大家来踩踩~🌺
🌊 《IDEA开发秘籍》学会IDEA常用操作,工作效率翻倍~💐
🪁 希望本文能够给您带来一定的帮助🌸文章粗浅,敬请批评指正!🐥

摘要:

本文是《100天精通Golang(基础入门篇)》系列的第12天,主要深入解析Go语言中的集合(Map)及常用函数的应用。文章从介绍什么是Map开始,然后详细讲解了Map的使用方法,包括使用make()函数创建map、delete()函数的使用、ok-idiom的应用、获取map的长度以及map作为引用类型的特点。此外,还提供了多个综合代码案例,帮助读者更好地理解和应用所学知识。通过本文的学习,读者将对Go语言中的集合(Map)有更深入的了解。

前言:

Go语言中的集合(Map)是一种重要的数据结构,它可以存储键值对,并提供了快速的查找和插入操作。在本篇文章中,我们将详细介绍Map的使用方法,并结合实际代码案例进行讲解。通过学习本文,读者将能够掌握如何正确地创建和操作Map,并了解其常用的函数应用。这将为读者打下坚实的基础,为进一步深入学习和应用Go语言打下基础。

一、集合(Map)

1.1 什么是Map

map是Go中的内置类型,它将一个值与一个键关联起来。可以使用相应的键检索值。

Map 是一种无序的键值对的集合。Map 最重要的一点是通过 key 来快速检索数据,key 类似于索引,指向数据的值

Map 是一种集合,所以我们可以像迭代数组和切片那样迭代它。不过,Map 是无序的,我们无法决定它的返回顺序,这是因为 Map 是使用 hash 表来实现的,也是引用类型

使用map过程中需要注意的几点:

  • map是无序的,每次打印出来的map都会不一样,它不能通过index获取,而必须通过key获取
  • map的长度是不固定的,也就是和slice一样,也是一种引用类型
  • 内置的len函数同样适用于map,返回map拥有的key的数量
  • map的key可以是所有可比较的类型,如布尔型、整数型、浮点型、复杂型、字符串型……也可以键。

1.2 Map的使用

1.2.1 使用make()创建map

可以使用内建函数 make 也可以使用 map 关键字来定义 Map:

/* 声明变量,默认 map 是 nil */
var map_variable map[key_data_type]value_data_type
/* 使用 make 函数 */
map_variable = make(map[key_data_type]value_data_type)
rating := map[string]float32 {"C":5, "Go":4.5, "Python":4.5, "C++":2 }

如果不初始化 map,那么就会创建一个 nil map。nil map 不能用来存放键值对

package main
import "fmt"
func main() {
   var countryCapitalMap map[string]string
   /* 创建集合 */
   countryCapitalMap = make(map[string]string)
   /* map 插入 key-value 对,各个国家对应的首都 */
   countryCapitalMap["France"] = "Paris"
   countryCapitalMap["Italy"] = "Rome"
   countryCapitalMap["Japan"] = "Tokyo"
   countryCapitalMap["India"] = "New Delhi"
   /* 使用 key 输出 map 值 */
   for country := range countryCapitalMap {
      fmt.Println("Capital of",country,"is",countryCapitalMap[country])
   }
   /* 查看元素在集合中是否存在 */
   captial, ok := countryCapitalMap["United States"]
   /* 如果 ok 是 true, 则存在,否则不存在 */
   if(ok){
      fmt.Println("Capital of United States is", captial)  
   }else {
      fmt.Println("Capital of United States is not present") 
   }
}

运行结果:

Capital of France is Paris
Capital of Italy is Rome
Capital of Japan is Tokyo
Capital of India is New Delhi
Capital of United States is not present

1.2.2 delete() 函数

delete(map, key) 函数用于删除集合的元素, 参数为 map 和其对应的 key。删除函数不返回任何值。

package main
import "fmt"
func main() {   
   /* 创建 map */
   countryCapitalMap := map[string] string {"France":"Paris","Italy":"Rome","Japan":"Tokyo","India":"New Delhi"}
   fmt.Println("原始 map")   
   /* 打印 map */
   for country := range countryCapitalMap {
      fmt.Println("Capital of",country,"is",countryCapitalMap[country])
   }
   /* 删除元素 */
   delete(countryCapitalMap,"France");
   fmt.Println("Entry for France is deleted")  
   fmt.Println("删除元素后 map")   
   /* 打印 map */
   for country := range countryCapitalMap {
      fmt.Println("Capital of",country,"is",countryCapitalMap[country])
   }
}

运行结果:

原始 map
Capital of France is Paris
Capital of Italy is Rome
Capital of Japan is Tokyo
Capital of India is New Delhi
Entry for France is deleted
删除元素后 map
Capital of Italy is Rome
Capital of Japan is Tokyo
Capital of India is New Delhi

1.2.3 ok-idiom

我们可以通过key获取map中对应的value值。语法为:

map[key]

但是当key如果不存在的时候,我们会得到该value值类型的默认值,比如string类型得到空字符串,int类型得到0。但是程序不会报错。

所以我们可以使用ok-idiom获取值,可知道key/value是否存在

value, ok := map[key]

示例代码:

package main
import (
  "fmt"
)
func main() {
  m := make(map[string]int)
  m["a"] = 1
  x, ok := m["b"]
  fmt.Println(x, ok)
  x, ok = m["a"]
  fmt.Println(x, ok)
}

运行结果:

0 false
1 true

1.2.4 map的长度

使用len函数可以确定map的长度。

len(map)  // 可以得到map的长度

1.2.5 map是引用类型的

与切片相似,映射是引用类型。当将映射分配给一个新变量时,它们都指向相同的内部数据结构。因此,一个的变化会反映另一个。

示例代码:

package main
import (  
    "fmt"
)
func main() {  
    personSalary := map[string]int{
        "steve": 12000,
        "jamie": 15000,
    }
    personSalary["mike"] = 9000
    fmt.Println("Original person salary", personSalary)
    newPersonSalary := personSalary
    newPersonSalary["mike"] = 18000
    fmt.Println("Person salary changed", personSalary)
}

运行结果:

Original person salary map[steve:12000 jamie:15000 mike:9000]  
Person salary changed map[steve:12000 jamie:15000 mike:18000]

map不能使用==操作符进行比较。==只能用来检查map是否为空。否则会报错:invalid operation: map1 == map2 (map can only be comparedto nil)

综合代码案例

综合代码案例1 :

package main
import "fmt"
func main() {
  /*
    map:映射,是一种专门用于存储键值对的集合。属于引用类型
    存储特点:
      A:存储的是无序的键值对
      B:键不能重复,并且和value值一一对应的。
          map中的key不能重复,如果重复,那么新的value会覆盖原来的,程序不会报错。
    语法结构:
      1.创建map
        var map1 map[key类型]value类型
          nil map,无法直接使用
        var map2 = make(map[key类型])value类型
        var map3 = map[key类型]value类型{key:value,key:value,key:value...}
      2.添加/修改
        map[key]=value
          如果key不存在,就是添加数据
          如果key存在,就是修改数据
      3.获取
        map[key]-->value
        value,ok := map[key]
          根据key获取对应的value
            如果key存在,value就是对应的数据,ok为true
            如果key不存在,value就是值类型的默认值,ok为false
      4.删除数据:
        delete(map,key)
          如果key存在,就可以直接删除
          如果key不存在,删除失败
      5.长度:
        len()
    每种数据类型:
      int:0
      float:0.0-->0
      string:""
      array:[00000]
      slice:nil
      map:nil
  */
  //1.创建map
  var map1 map[int]string         //没有初始化,nil
  var map2 = make(map[int]string) //创建
  var map3 = map[string]int{"Go": 98, "Python": 87, "Java": 79, "Html": 93}
  fmt.Println(map1)
  fmt.Println(map2)
  fmt.Println(map3)
  fmt.Println(map1 == nil)
  fmt.Println(map2 == nil)
  fmt.Println(map3 == nil)
  //2.nil map
  if map1 == nil {
    map1 = make(map[int]string)
    fmt.Println(map1 == nil)
  }
  //3.存储键值对到map中
  //map1[key] = value
  map1[1] = "hello" //panic: assignment to entry in nil map
  map1[2] = "world"
  map1[3] = "memeda"
  map1[4] = "libin9ioak"
  map1[5] = "ruby"
  map1[6] = "libin9iOak"
  map1[7] = ""
  //4.获取数据,根据key获取对应的value值
  //根据key获取对应的value,如果key存在,获取数值,如果key不存在,获取的是value值类型的零值
  fmt.Println(map1)
  fmt.Println(map1[4])  //根据key为4,获取对应的value值
  fmt.Println(map1[40]) //""
  v1, ok := map1[40]
  if ok {
    fmt.Println("对应的数值是:", v1)
  } else {
    fmt.Println("操作的key不存在,获取到的是零值:", v1)
  }
  //5.修改数据
  fmt.Println(map1)
  map1[3] = "李如花"
  fmt.Println(map1)
  //6.删除数据
  delete(map1, 3)
  fmt.Println(map1)
  delete(map1, 30)
  fmt.Println(map1)
  //7.长度
  fmt.Println(len(map1))
}

运行结果:

GOROOT=D:\Go #gosetup
GOPATH=C:\Users\DELL\go #gosetup
D:\Go\bin\go.exe build -o C:\Users\DELL\AppData\Local\JetBrains\GoLand2023.1\tmp\GoLand\___go_build_Day12_Map.exe Day12-Map #gosetup
C:\Users\DELL\AppData\Local\JetBrains\GoLand2023.1\tmp\GoLand\___go_build_Day12_Map.exe
map[]
map[]
map[Go:98 Html:93 Java:79 Python:87]
true
false
false
false
map[1:hello 2:world 3:memeda 4:libin9ioak 5:ruby 6:libin9iOak 7:]
libin9ioak
操作的key不存在,获取到的是零值:
map[1:hello 2:world 3:memeda 4:libin9ioak 5:ruby 6:libin9iOak 7:]
map[1:hello 2:world 3:李如花 4:libin9ioak 5:ruby 6:libin9iOak 7:]
map[1:hello 2:world 4:libin9ioak 5:ruby 6:libin9iOak 7:]
map[1:hello 2:world 4:libin9ioak 5:ruby 6:libin9iOak 7:]
6
进程 已完成,退出代码为 0

运行截图:


         

综合代码案例2:

package main
import (
  "fmt"
  "sort"
)
func main() {
  /*
    map的遍历:
      使用:for range
        数组,切片:index,value
        map:key,value
  */
  map1 := make(map[int]string)
  map1[1] = "小红"
  map1[2] = "小风"
  map1[3] = "小白"
  map1[4] = "小贞"
  map1[5] = "大王"
  map1[6] = "小王"
  //1.遍历map
  for k, v := range map1 {
    fmt.Println(k, v)
  }
  fmt.Println("----------------------")
  for i := 1; i <= len(map1); i++ {
    fmt.Println(i, "--->", map1[i])
  }
  /*
    1.获取所有的key,-->切片/数组
    2.进行排序
    3.遍历key,--->map[key]
  */
  keys := make([]int, 0, len(map1))
  fmt.Println(keys)
  for k, _ := range map1 {
    keys = append(keys, k)
  }
  fmt.Println(keys)
  //冒泡排序,或者使用sort包下的排序方法
  sort.Ints(keys)
  fmt.Println(keys)
  for _, key := range keys {
    fmt.Println(key, map1[key])
  }
  s1 := []string{"Apple", "Windows", "Orange", "Inter", "小王", "18", "女"}
  fmt.Println(s1)
  sort.Strings(s1)
  fmt.Println(s1)
}

运行结果:

GOROOT=D:\Go #gosetup
GOPATH=C:\Users\DELL\go #gosetup
D:\Go\bin\go.exe build -o C:\Users\DELL\AppData\Local\JetBrains\GoLand2023.1\tmp\GoLand\___go_build_Day12_Map__1_.exe D:\GolandProjects\Day12-Map\MapDemo2.go #gosetup
C:\Users\DELL\AppData\Local\JetBrains\GoLand2023.1\tmp\GoLand\___go_build_Day12_Map__1_.exe
3 小白
4 小贞
5 大王
6 小王
1 小红
2 小风
----------------------
1 ---> 小红
2 ---> 小风
3 ---> 小白
4 ---> 小贞
5 ---> 大王
6 ---> 小王
[]
[5 6 1 2 3 4]
[1 2 3 4 5 6]
1 小红
2 小风
3 小白
4 小贞
5 大王
6 小王
[Apple Windows Orange Inter 小王 18 女]
[18 Apple Inter Orange Windows 女 小王]
进程 已完成,退出代码为 0

运行截图:


         

综合代码案例3 :

package main
import "fmt"
func main() {
  /*
    map和slice的结合使用:
      1.创建map用于存储人的信息
        name,age,sex,address
      2.每个map存储一个人的信息
      3.将这些map存入到slice中
      4.打印遍历输出
  */
  //1.创建map存储第一个人的信息
  map1 := make(map[string]string)
  map1["name"] = "小张"
  map1["age"] = "22"
  map1["sex"] = "男"
  map1["address"] = "北京市海淀区XX路XX号"
  fmt.Println(map1)
  //2.第二个人
  map2 := make(map[string]string)
  map2["name"] = "小李"
  map2["age"] = "20"
  map2["sex"] = "女性"
  map2["address"] = "上海市闵行三角洲"
  fmt.Println(map2)
  //3.
  map3 := map[string]string{"name": "go", "age": "16", "sex": "女性", "address": "谷歌"}
  fmt.Println(map3)
  //将map存入到slice中
  s1 := make([]map[string]string, 0, 3)
  s1 = append(s1, map1)
  s1 = append(s1, map2)
  s1 = append(s1, map3)
  //遍历切片
  for i, val := range s1 {
    //val :map1,map2,map3
    fmt.Printf("第 %d 个人的信息是:\n", i+1)
    fmt.Printf("\t姓名:%s\n", val["name"])
    fmt.Printf("\t年龄:%s\n", val["age"])
    fmt.Printf("\t性别:%s\n", val["sex"])
    fmt.Printf("\t地址:%s\n", val["address"])
  }
}

运行结果:

GOROOT=D:\Go #gosetup
GOPATH=C:\Users\DELL\go #gosetup
D:\Go\bin\go.exe build -o C:\Users\DELL\AppData\Local\JetBrains\GoLand2023.1\tmp\GoLand\___go_build_Day12_Map__2_.exe D:\GolandProjects\Day12-Map\MapDemo3.go #gosetup
C:\Users\DELL\AppData\Local\JetBrains\GoLand2023.1\tmp\GoLand\___go_build_Day12_Map__2_.exe
map[address:北京市海淀区XX路XX号 age:22 name:小张 sex:男]
map[address:上海市闵行三角洲 age:20 name:小李 sex:女性]
map[address:谷歌 age:16 name:go sex:女性]
第 1 个人的信息是:
        姓名:小张
        年龄:22
        性别:男
        地址:北京市海淀区XX路XX号
第 2 个人的信息是:
        姓名:小李
        年龄:20
        性别:女性
        地址:上海市闵行三角洲
第 3 个人的信息是:
        姓名:go
        年龄:16
        性别:女性
        地址:谷歌
进程 已完成,退出代码为 0

运行截图:


         

综合代码案例4 :

package main
import "fmt"
func main() {
  /*
    一:数据类型:
      基本数据类型:int,float,string,bool
      复合数据类型:array,slice,map,function,pointer,struct。。。
        array:[size]数据类型
        slice:[]数据类型
        map:map[key的类型]value的类型
    二:存储特点:
      值类型:int,float,string,bool,array,struct
      引用类型:slice,map
        make(),slice,map,chan
  */
  map1 := make(map[int]string)
  map2 := make(map[string]float64)
  fmt.Printf("%T\n", map1)
  fmt.Printf("%T\n", map2)
  map3 := make(map[string]map[string]string) //map[string]map[string]string
  m1 := make(map[string]string)
  m1["name"] = "小李"
  m1["age"] = "22"
  m1["salary"] = "999999"
  map3["hr"] = m1
  m2 := make(map[string]string)
  m2["name"] = "go"
  m2["age"] = "16"
  m2["salary"] = "80000"
  map3["总经理"] = m1
  fmt.Println(map3)
  fmt.Println("---------------")
  map4 := make(map[string]string)
  map4["小王"] = "美"
  map4["小李"] = "富"
  map4["小文"] = "白"
  fmt.Println(map4)
  map5 := map4
  fmt.Println(map5)
  map5["小昭"] = "富"
  fmt.Println(map4)
  fmt.Println(map5)
}

运行结果:

GOROOT=D:\Go #gosetup
GOPATH=C:\Users\DELL\go #gosetup
D:\Go\bin\go.exe build -o C:\Users\DELL\AppData\Local\JetBrains\GoLand2023.1\tmp\GoLand\___go_build_Day12_Map__3_.exe D:\GolandProjects\Day12-Map\MapDemo4.go #gosetup
C:\Users\DELL\AppData\Local\JetBrains\GoLand2023.1\tmp\GoLand\___go_build_Day12_Map__3_.exe
map[int]string
map[string]float64
map[hr:map[age:22 name:小李 salary:999999] 总经理:map[age:22 name:小李 salary:999999]]
---------------
map[小文:白 小李:富 小王:美]
map[小文:白 小李:富 小王:美]
map[小文:白 小昭:富 小李:富 小王:美]
map[小文:白 小昭:富 小李:富 小王:美]
进程 已完成,退出代码为 0

运行截图:


         

今日学习总结:

在今天的学习中,我们深入解析了Go语言中的集合(Map)及其常用函数应用。首先,我们了解了什么是Map,它是一种存储键值对的数据结构。然后,我们学习了创建Map的方法,使用make()函数进行创建,并了解了delete()函数的使用以及ok-idiom的应用。我们还了解到,Map是引用类型的,可以传递和修改。最后,我们通过多个综合代码案例加深了对Map的理解,提供了实际应用的示例。通过今天的学习,我们对Go语言中的Map有了更深入的了解,并掌握了一些常用的函数应用。

结语

通过今天的学习,您已经踏上了Golang的学习之旅。在未来的日子里,您将探索Golang的各个方面,从基础概念到高级技巧,从实际应用到性能优化。

学习一门编程语言是一个持续的过程,每一天都是您向Golang的精通迈进的重要一步。我鼓励您坚持每天学习,保持热情和好奇心,解决挑战并享受成功的喜悦。

在您的学习旅程中,不要忘记参与社区和与其他Golang开发者交流。分享您的见解和经验,向他人学习,并在开源项目或实际应用中展示您的技能。

如果您在学习过程中遇到困难或有任何问题,不要犹豫向社区和专家寻求帮助。持续学习,勇敢探索,您将在Golang领域取得令人瞩目的成就。

最后,感谢您的阅读和支持!祝愿您在未来的每一天中都能够成为一名精通Golang的开发者!

期待听到您在学习过程中的进展和成就。如果您需要进一步的帮助,请随时告诉我。祝您在学习Golang的旅程中取得巨大成功!

点击下方名片,加入IT技术核心学习团队。一起探索科技的未来,共同成长。

如果您在学习过程中有任何疑惑,请点击下方名片,带您一对一快速入门 Go语言 的世界 ~

目录
相关文章
|
机器学习/深度学习 文字识别 监控
安全监控系统:技术架构与应用解析
该系统采用模块化设计,集成了行为识别、视频监控、人脸识别、危险区域检测、异常事件检测、日志追溯及消息推送等功能,并可选配OCR识别模块。基于深度学习与开源技术栈(如TensorFlow、OpenCV),系统具备高精度、低延迟特点,支持实时分析儿童行为、监测危险区域、识别异常事件,并将结果推送给教师或家长。同时兼容主流硬件,支持本地化推理与分布式处理,确保可靠性与扩展性,为幼儿园安全管理提供全面解决方案。
846 3
|
12月前
|
存储 安全 Java
【Golang】(4)Go里面的指针如何?函数与方法怎么不一样?带你了解Go不同于其他高级语言的语法
结构体可以存储一组不同类型的数据,是一种符合类型。Go抛弃了类与继承,同时也抛弃了构造方法,刻意弱化了面向对象的功能,Go并非是一个传统OOP的语言,但是Go依旧有着OOP的影子,通过结构体和方法也可以模拟出一个类。
523 2
|
12月前
|
存储 Java Go
【Golang】(3)条件判断与循环?切片和数组的关系?映射表与Map?三组关系傻傻分不清?本文带你了解基本的复杂类型与执行判断语句
在Go中,条件控制语句总共有三种if、switch、select。循环只有for,不过for可以充当while使用。如果想要了解这些知识点,初学者进入文章中来感受吧!
397 2
|
存储 Java Go
对比Java学习Go——函数、集合和OOP
Go语言的函数支持声明与调用,具备多返回值、命名返回值等特性,结合`func`关键字与类型后置语法,使函数定义简洁直观。函数可作为一等公民传递、赋值或作为参数,支持匿名函数与闭包。Go通过组合与接口实现面向对象编程,结构体定义数据,方法定义行为,接口实现多态,体现了Go语言的简洁与高效设计。
366 4
|
Linux Go iOS开发
IDA 9.2 发布:Golang 改进、新 UI 组件、类型解析等
IDA Pro 9.2 (macOS, Linux, Windows) - 强大的反汇编程序、反编译器和多功能调试器
1782 0
|
人工智能 Dart Go
Go语言中的make和new函数的区别及使用场景
本文详细解析了Go语言中`make`和`new`函数的使用方法及区别。`make`用于创建切片、映射和通道等引用类型,返回初始化后的值;`new`用于创建任意类型的零值对象,返回指向该对象的指针。文章通过多个示例说明两者的应用场景,并总结了面试中可能遇到的相关问题,如底层实现、使用场景及优缺点等,帮助读者更好地理解和区分这两个函数。
452 1
|
Go Python
函数的定义与调用 -《Go语言实战指南》
本文介绍了 Go 语言中函数的核心特性与用法,包括基本定义格式、调用方式、多返回值、返回值命名、参数类型简写、可变参数、高阶函数及匿名函数等内容。通过示例代码详细展示了如何定义和使用不同类型的函数,使读者能够全面了解 Go 函数的灵活性与强大功能。
368 12
|
人工智能 API 开发者
HarmonyOS Next~鸿蒙应用框架开发实战:Ability Kit与Accessibility Kit深度解析
本书深入解析HarmonyOS应用框架开发,聚焦Ability Kit与Accessibility Kit两大核心组件。Ability Kit通过FA/PA双引擎架构实现跨设备协同,支持分布式能力开发;Accessibility Kit提供无障碍服务构建方案,优化用户体验。内容涵盖设计理念、实践案例、调试优化及未来演进方向,助力开发者打造高效、包容的分布式应用,体现HarmonyOS生态价值。
1121 27
|
Go 调度
GO语言函数的内部运行机制分析
以上就是Go语言中函数的内部运行机制的概述,展示了函数在Go语言编程中如何发挥作用,以及Go如何使用简洁高效的设计,使得代码更简单,更有逻辑性,更易于理解和维护。尽管这些内容深入了一些底层的概念,但我希望通过这种方式,将这些理论知识更生动、更形象地带给你,让你在理解的同时找到编程的乐趣。
292 5
|
Web App开发 移动开发 前端开发
React音频播放器样式自定义全解析:从入门到避坑指南
在React中使用HTML5原生&lt;audio&gt;标签时,开发者常面临视觉一致性缺失、样式定制局限和交互体验割裂等问题。通过隐藏原生控件并构建自定义UI层,可以实现完全可控的播放器视觉风格,避免状态不同步等典型问题。结合事件监听、进度条拖拽、浏览器兼容性处理及性能优化技巧,可构建高性能、可维护的音频组件,满足跨平台需求。建议优先使用成熟音频库(如react-player),仅在深度定制需求时采用原生方案。
739 12

热门文章

最新文章

推荐镜像

更多