Map 是 Go 中的内置类型,它将键与值绑定到一起。可以通过键获取相应的值。

如何创建 map?

可以通过将键和值的类型传递给内置函数 make 来创建一个 map。语法为:make(map[KeyType]ValueType)。(译者注:map 的类型表示为 map[KeyType]ValueType)例如:

  1. personSalary := make(map[string]int)

上面的代码创建了一个名为 personSalary 的 map。其中键的类型为 string,值的类型为 int。

map 的 0 值为 nil。试图给一个 nil map 添加元素给会导致运行时错误。因此 map 必须通过 make 来初始化(也可以使用速记声明来创建 map

  1. package main
  2.  
  3. import (
  4. "fmt"
  5. )
  6.  
  7. func main() {
  8. var personSalary map[string]int
  9. if personSalary == nil {
  10. fmt.Println("map is nil. Going to make one.")
  11. personSalary = make(map[string]int)
  12. }
  13. }

  

上面的程序中,personSalary 为 nil,因此使用 make 初始化它。程序的输出为:map is nil. Going to make one.

向 map 中插入元素

插入元素给 map 的语法与数组相似。下面的代码插入一些新的元素给 map personSalary

  1. package main
  2.  
  3. import (
  4. "fmt"
  5. )
  6.  
  7. func main() {
  8. personSalary := make(map[string]int)
  9. personSalary["steve"] = 12000
  10. personSalary["jamie"] = 15000
  11. personSalary["mike"] = 9000
  12. fmt.Println("personSalary map contents:", personSalary)
  13. }

  

上面的程序输出:personSalary map contents: map[steve:12000 jamie:15000 mike:9000]

也可以在声明时初始化一个数组:

  1. package main
  2.  
  3. import (
  4. "fmt"
  5. )
  6.  
  7. func main() {
  8. personSalary := map[string]int {
  9. "steve": 12000,
  10. "jamie": 15000,
  11. }
  12. personSalary["mike"] = 9000
  13. fmt.Println("personSalary map contents:", personSalary)
  14. }

  

上面的程序在声明 personSalary 的同时向其中

插入了两个元素。接着插入了一个以 "mike" 为键的元素。程序的输出为:

  1. personSalary map contents: map[steve:12000 jamie:15000 mike:9000]

string 并不是可以作为键的唯一类型,其他所有可以比较的类型,比如,布尔类型,整型,浮点型,复数类型都可以作为键。如果你想了解更多关于可比较类型的话,请参阅:http://golang.org/ref/spec#Comparison_operators

访问 map 中的元素

现在我们已经添加了一些元素给 map,现在让我们学习如何从 map 中提取它们。根据键获取值的语法为:map[key],例如:

  1. package main
  2.  
  3. import (
  4. "fmt"
  5. )
  6.  
  7. func main() {
  8. personSalary := map[string]int{
  9. "steve": 12000,
  10. "jamie": 15000,
  11. }
  12. personSalary["mike"] = 9000
  13. employee := "jamie"
  14. fmt.Println("Salary of", employee, "is", personSalary[employee])
  15. }

上面的程序非常简单。员工 jamie 的工资被取出并打印。程序的输出为:Salary of jamie is 15000

如果一个键不存在会发生什么?map 会返回值类型的 0 值。比如如果访问了 personSalary 中的不存在的键,那么将返回 int 的 0 值,也就是 0。

  1. package main
  2.  
  3. import (
  4. "fmt"
  5. )
  6.  
  7. func main() {
  8. personSalary := map[string]int{
  9. "steve": 12000,
  10. "jamie": 15000,
  11. }
  12. personSalary["mike"] = 9000
  13. employee := "jamie"
  14. fmt.Println("Salary of", employee, "is", personSalary[employee])
  15. fmt.Println("Salary of joe is", personSalary["joe"])
  16. }

上面的程序输出为:

  1. Salary of jamie is 15000
  2. Salary of joe is 0

上面的程序返回 joe 的工资为 0。我们没有得到任何运行时错误说明键 joe 在 personSalary 中不存在。

我们如何检测一个键是否存在于一个 map 中呢?可以使用下面的语法:

  1. value, ok := map[key]

上面的语法可以检测一个特定的键是否存在于 map 中。如果 ok 是 true,则键存在,value 被赋值为对应的值。如果 ok为 false,则表示键不存在。

  1. package main
  2.  
  3. import (
  4. "fmt"
  5. )
  6.  
  7. func main() {
  8. personSalary := make(map[string]int)
  9. personSalary["steve"] = 12000
  10. personSalary["jamie"] = 15000
  11. personSalary["mike"] = 9000
  12. fmt.Println("personSalary map contents:", personSalary)
  13.  
  14. value, ok := personSalary["Tom"]
  15. if ok == true {
  16. fmt.Println(value)
  17. } else {
  18. fmt.Println("Tom is not exist")
  19. }
  20.  
  21. }

  在上面的程序中,第 15 行,ok 应该为 false 因为 Tom不存在。因此程序的输出为:

  1. Tom is not exist

  

range for 可用于遍历 map 中所有的元素(译者注:这里 range 操作符会返回 map 的键和值)。

  1. package main
  2.  
  3. import (
  4. "fmt"
  5. )
  6.  
  7. func main() {
  8. personSalary := map[string]int{
  9. "steve": 12000,
  10. "jamie": 15000,
  11. }
  12. personSalary["mike"] = 9000
  13. fmt.Println("All items of a map")
  14. for key, value := range personSalary {
  15. fmt.Printf("personSalary[%s] = %d\n", key, value)
  16. }
  17.  
  18. }

上面的程序输出如下:

  1. All items of a map
  2. personSalary[mike] = 9000
  3. personSalary[steve] = 12000
  4. personSalary[jamie] = 15000

值得注意的是,因为 map 是无序的,因此对于程序的每次执行,不能保证使用 range for 遍历 map 的顺序总是一致的。

删除元素

delete(map, key) 用于删除 map 中的 key。delete 函数没有返回值。

  1. package main
  2.  
  3. import (
  4. "fmt"
  5. )
  6.  
  7. func main() {
  8. personSalary := map[string]int{
  9. "steve": 12000,
  10. "jamie": 15000,
  11. }
  12. personSalary["mike"] = 9000
  13. fmt.Println("map before deletion", personSalary)
  14. delete(personSalary, "steve")
  15. fmt.Println("map after deletion", personSalary)
  16.  
  17. }

上面的程序删除以 steve 为键的元素。程序输出为:

  1. map before deletion map[steve:12000 jamie:15000 mike:9000]
  2. map after deletion map[mike:9000 jamie:15000]

map 的大小

用内置函数 len 获取 map 的大小:

  1. package main
  2.  
  3. import (
  4. "fmt"
  5. )
  6.  
  7. func main() {
  8. personSalary := map[string]int{
  9. "steve": 12000,
  10. "jamie": 15000,
  11. }
  12. personSalary["mike"] = 9000
  13. fmt.Println("length is", len(personSalary))
  14.  
  15. }

上面程序中,len(personSalary) 获取 personSalary 的大小。上面的程序输出:length is 3

map 是引用类型

切片一样,map 是引用类型。当一个 map 赋值给一个新的变量,它们都指向同一个内部数据结构。因此改变其中一个也会反映到另一个:

  1. package main
  2.  
  3. import (
  4. "fmt"
  5. )
  6.  
  7. func main() {
  8. personSalary := map[string]int{
  9. "steve": 12000,
  10. "jamie": 15000,
  11. }
  12. personSalary["mike"] = 9000
  13. fmt.Println("Original person salary", personSalary)
  14. newPersonSalary := personSalary
  15. newPersonSalary["mike"] = 18000
  16. fmt.Println("Person salary changed", personSalary)
  17. }

上面的程序中,第 14 行,personSalary 赋值给 newPersonSalary。下一行,将 newPersonSalary 中 mike 的工资改为 18000。那么在 personSalary 中 mike 的工资也将变为 18000。程序的输出如下:

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

将 map 作为参数传递给函数也是一样的。在函数中对 map 的任何修改都会影响在调用函数中看到。

  1. package main
  2. import (
  3. "fmt"
  4. )
  5. func main() {
  6. personSalary := make(map[string]int)
  7. personSalary["steve"] = 12000
  8. personSalary["jamie"] = 15000
  9. personSalary["mike"] = 9000
  10. fmt.Println("personSalary map contents:", personSalary)
  11. value, ok := personSalary["Tom"]
  12. if ok == true {
  13. fmt.Println(value)
  14. } else {
  15. fmt.Println("Tom is not exist")
  16. }
  17. for k, v := range personSalary {
  18. fmt.Println(k, v)
  19. }
  20. fmt.Println("Len: ", len(personSalary))
  21. delete(personSalary, "mike")
  22. for k, v := range personSalary {
  23. fmt.Println(k, v)
  24. }
  25. fmt.Println("Len: ", len(personSalary))
  26. newPersionSalary := personSalary
  27. newPersionSalary["tom"] = 5000
  28. for k, v := range personSalary {
  29. fmt.Println(k, v)
  30. }
  31. fmt.Println("Len: ", len(newPersionSalary))
  32. for k, v := range newPersionSalary {
  33. fmt.Println(k, v)
  34. }
  35. fmt.Println("Len: ", len(newPersionSalary))
  36. }

  

  

GoLang基础数据类型---字典的更多相关文章

  1. GoLang基础数据类型--->字典(map)详解

    GoLang基础数据类型--->字典(map)详解 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任.   可能大家刚刚接触Golang的小伙伴都会跟我一样,这个map是干嘛的,是 ...

  2. GoLang基础数据类型-切片(slice)详解

    GoLang基础数据类型-切片(slice)详解 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 数组的长度在定义之后无法再次修改:数组是值类型,每次传递都将产生一份副本.显然这种数 ...

  3. GoLang基础数据类型--->数组(array)详解

    GoLang基础数据类型--->数组(array)详解 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 一.Golang数组简介 数组是Go语言编程中最常用的数据结构之一.顾名 ...

  4. GoLang基础数据类型--->字符串处理大全

    GoLang基础数据类型--->字符串处理大全 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 欢迎加入:   高级运维工程师之路               59843264 ...

  5. Python基础数据类型-字典(dict)

    Python基础数据类型-字典(dict) 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 本篇博客使用的是Python3.6版本,以及以后分享的每一篇都是Python3.x版本的哟 ...

  6. golang基础--map字典

    map 类似python语言中的dict(字典类型),以key-value形式存储数据 Key必须是支持==或!=比较运算的类型,不可以是函数,map或slice map查找比线性搜素快很多,但比使用 ...

  7. Python基础数据类型之字典

      基础数据类型之字典 ps:数据类型划分:可变数据类型和不可变数据类型. 不可变数据类型:元组(tupe).布尔值(bool).整数型(int).字符串(str).不可变数据类型也称为可哈希. 可变 ...

  8. python的学习笔记01_4基础数据类型列表 元组 字典 集合 其他其他(for,enumerate,range)

    列表 定义:[]内以逗号分隔,按照索引,存放各种数据类型,每个位置代表一个元素 特性: 1.可存放多个值 2.可修改指定索引位置对应的值,可变 3.按照从左到右的顺序定义列表元素,下标从0开始顺序访问 ...

  9. Py西游攻关之基础数据类型(四)-字典

    Py西游攻关之基础数据类型 - Yuan先生 https://www.cnblogs.com/yuanchenqi/articles/5782764.html 七 Dictionary(字典) 字典是 ...

随机推荐

  1. SpringCloud基本模块分配搭建以及负载均衡

    springcloud是基于springboot的一套微服务的解决方案,springboot可以快速构建单个应用服务,而springcloud没有重复造轮子而是将现有的技术(服务发现,负载均衡等)整合 ...

  2. 洛谷P1084 疫情控制

    题目 细节比较多的二分+跟LCA倍增差不多的思想 首先有这样一个贪心思路,深度越低的检查点越好,而最长时间和深度具有单调性,即给定时间越长,每个军队能向更浅的地方放置检查点.因此可以考虑二分时间,然后 ...

  3. 第08组 Alpha冲刺(5/6)

    队名:955 组长博客:https://www.cnblogs.com/cclong/p/11898112.html 作业博客:https://edu.cnblogs.com/campus/fzu/S ...

  4. Android Studio 本地化操作

    1.打开 string.xml 文件,在右上角,点 open-editor 2.点左上角的“地球”图标,就会弹出选择国家列表,输入zh会自动筛选,能很快选到中国简体中文 3.选择后,会在原来的列表中添 ...

  5. [Gamma]Scrum Meeting#1

    github 本次会议项目由PM召开,时间为5月26日晚上10点30分 时长25分钟 任务表格 人员 昨日工作 下一步工作 木鬼 撰写博客,组织例会 swoip 前端显示屏幕,翻译坐标 bhlt 后端 ...

  6. Python3中通过fake_useragent生成随机UserAgent

    安装和使用 fake_useragent第三方库,来实现随机请求头的设置: GitHub               ---> https://github.com/hellysmile/fak ...

  7. 用Eclipse的maven方式创建JFinal项目

  8. 解析生效测试方法 执行命令 ping 域名 得不到 IP 主要有如下几个原因:

    https://help.aliyun.com/knowledge_detail/39834.html dig https://cloud.tencent.com/document/product/3 ...

  9. ES6 - 字符串的扩展(模版字符串)

    模板字面量的最简单语法,是使用反引号( `)(Tab上面那个键)来包裹普通字符串,而不是用双引号或单引号. <!DOCTYPE html> <html lang="en&q ...

  10. html css 浮层 侧边栏

    2019-7-1 16:02:25 星期一 实现的效果是点击, 然后从左侧滑出, 再点击, 就滑进去 <!DOCTYPE HTML> <html lang="en" ...