Go中字典类型是散列表(hash table)的一个实现,其官方称谓是map。
散列表是一个实现了关联数组的数据结构,关联数组是用于表示键值对的无序集合的一种抽象数据类型。
Go中称键值对为键-元素对,它把字典中的每个键都看作与其对应的元素的索引,这样的索引再同一个字典值中是唯一的。
下面的代码声明了一个字典类型的变量:

  1. var ipSwitches = map[string]bool{}

变量ipSwitches的键类型为string,元素类型为bool。
map[string]bool{}表示了一个不包含任何元素的字典值。
与切片类型一样,字典类型是一个引用类型。也正因此,字典类型的零值是nil。
字典值的长度表示了其中的键-元素对的数量,其零值的长度总是0.
将其作为语言内置类型,从运行时层面进行优化,可获得更高效的性能。
作为无序键值对集合,字典要求key必须是支持相等运算符(==、!=)的数据类型。

字典是引用类型,使用make函数或初始化表达式来创建。

  1. package main
  2.  
  3. import "fmt"
  4.  
  5. func main() {
  6. m := make(map[string]int) //make函数创建
  7. m["a"] = 1
  8. m["b"] = 2
  9.  
  10. m2 := map[int]struct { //key的类型int,value的类型struct
  11. x int
  12. }{
  13. 1: {x: 100},
  14. 2: {x: 200},
  15. }
  16. fmt.Println(m, m2) //map[a:1 b:2] map[1:{100} 2:{200}]
  17. }

字典的基本操作:增删改查

  1. package main
  2.  
  3. import "fmt"
  4.  
  5. func main() {
  6. m := map[string]int{
  7. "a": 1,
  8. "b": 2,
  9. }
  10.  
  11. m["a"] = 10 //修改
  12. m["c"] = 30 //添加
  13. fmt.Println(m) //map[a:10 b:2 c:30]
  14.  
  15. if v, ok := m["d"]; ok { //使用ok-idiom判断键是否存在
  16. fmt.Println(v)
  17. }
  18.  
  19. delete(m, "b") //删除一个键值对
  20. fmt.Println(m) //map[a:10 b:2 c:30]
  21. fmt.Println(m["f"]) //0 访问不存在的键值对时返回0值
  22. }

对字典进行迭代每次返回的键值次序都不相同

  1. package main
  2.  
  3. import "fmt"
  4.  
  5. func main() {
  6. m := make(map[string]int)
  7.  
  8. for i := 0; i < 7; i++ {
  9. m[string('a'+i)] = i
  10. }
  11.  
  12. for i := 0; i < 4; i++ {
  13. for k, v := range m {
  14. fmt.Printf("%s:%d ", k, v)
  15. }
  16. fmt.Println()
  17. }
  18. }
  19.  
  20. /*
  21. g:6 a:0 b:1 c:2 d:3 e:4 f:5
  22. e:4 f:5 g:6 a:0 b:1 c:2 d:3
  23. g:6 a:0 b:1 c:2 d:3 e:4 f:5
  24. a:0 b:1 c:2 d:3 e:4 f:5 g:6
  25. */

函数len返回当前键值对的数量,cap不接受字典类型.
因内存访问安全和哈希算法等缘故,字典被设计成"not addressable",
因此不能直接修改value成员(结构或数组)。

  1. package main
  2.  
  3. import "fmt"
  4.  
  5. func main() {
  6. type user struct {
  7. name string
  8. age int
  9. }
  10.  
  11. m := map[int]user{
  12. 1: {"kebi", 19},
  13. }
  14. fmt.Println(len(m)) //1
  15. fmt.Println(cap(m)) //invalid argument m (type map[int]user) for cap
  16. m[1].age += 1 // cannot assign to struct field m[1].age in map
  17. }

正确的做法是返回整个value,待修改后再设置字典键值,或直接用指针类型。

  1. package main
  2.  
  3. import "fmt"
  4.  
  5. func main() {
  6. type user struct {
  7. name string
  8. age int
  9. }
  10.  
  11. m := map[int]user{
  12. 1: {"kebi", 19},
  13. }
  14.  
  15. u := m[1] //取出整个value值
  16. u.age += 1 //现在操作的对象是结构体
  17. m[1] = u //重新赋值
  18. fmt.Println(m)
  19.  
  20. m2 := map[int]*user{ //value是指针类型
  21. 1: &user{"Jack", 20},
  22. }
  23. m2[1].age++ //m2[1]返回的是指针,透过指针修改目标对象
  24. fmt.Println(m2[1])
  25. }

 

不能对nil字典进行赋值操作,但却能读。

  1. package main
  2.  
  3. import "fmt"
  4.  
  5. func main() {
  6. var m map[string]int //只进行声明的字典是nil字典
  7. fmt.Println(m["a"]) //0
  8. // m["a"] = 1 //panic: assignment to entry in nil map
  9.  
  10. m2 := map[string]int{}
  11. fmt.Println(m == nil, m2 == nil) //true false
  12. }

在迭代期间删除或新增键值是安全的。

  1. package main
  2.  
  3. import "fmt"
  4.  
  5. func main() {
  6. m := make(map[int]int)
  7.  
  8. for i := 0; i < 10; i++ {
  9. m[i] = i + 10
  10. }
  11.  
  12. for k := range m {
  13. if k == 5 {
  14. m[100] = 1000
  15. }
  16. delete(m, k)
  17. fmt.Println(k, m)
  18. }
  19. }
  20.  
  21. /*
  22. 0 map[9:19 2:12 6:16 8:18 7:17 1:11 3:13 4:14 5:15]
  23. 2 map[5:15 7:17 1:11 3:13 4:14 8:18 9:19 6:16]
  24. 6 map[4:14 5:15 7:17 1:11 3:13 8:18 9:19]
  25. 8 map[7:17 1:11 3:13 4:14 5:15 9:19]
  26. 9 map[4:14 5:15 7:17 1:11 3:13]
  27. 1 map[3:13 4:14 5:15 7:17]
  28. 3 map[4:14 5:15 7:17]
  29. 4 map[5:15 7:17]
  30. 5 map[7:17 100:1000]
  31. 7 map[100:1000]
  32. */

运行时会对字典并发操作做出检测.如果某个任务正在对字典进行写操作,
那么其它任务就不能对该字典执行并发操作(读写删除),否则会导致进程崩溃.

  1. package main
  2.  
  3. import "time"
  4.  
  5. func main() {
  6. m := make(map[string]int)
  7.  
  8. go func() {
  9. for {
  10. m["a"] += 1
  11. time.Sleep(time.Microsecond)
  12. }
  13. }()
  14.  
  15. go func() {
  16. for {
  17. _ = m["b"]
  18. time.Sleep(time.Microsecond)
  19. }
  20. }()
  21. select {}
  22. }
  23.  
  24. //fatal error: concurrent map read and map write

 

go——字典的更多相关文章

  1. 【DG】Oracle_Data_Guard官方直译

    [DG]Oracle Data Guard官方直译 1 Oracle Data Guard 介绍   Oracle Data Guard概念和管理10g版本2   Oracle Data Guard ...

  2. DVWA实验之Brute Force(暴力破解)- Low

    DVWA实验之Brute Force-暴力破解- Low     这里开始DVWA的相关实验~   有关DVWA环境搭建的教程请参考: https://www.cnblogs.com/0yst3r-2 ...

  3. Oracle错误览表

    Oracle 错误总结及问题解决 ORA     本文转自:https://www.cnblogs.com/zhangwei595806165/p/4972016.html  作者@承影剑 ORA-0 ...

  4. Javacript实现字典结构

    字典是一种用[键,值]形式存储元素的数据结构.也称作映射,ECMAScript6中,原生用Map实现了字典结构. 下面代码是尝试用JS的Object对象来模拟实现一个字典结构. <script& ...

  5. python 数据类型 ----字典

    字典由一对key:value 组成的 python中常用且重量级的数据类型 1. key , keys, values 字典由一对key:value 组成的 python中常用且重量级的数据类型 1. ...

  6. 增强版字典DictionaryEx

    代码 public class DictionaryEx<TKey, TValue> : IDictionary<TKey, TValue> { /// <summary ...

  7. python学习笔记(字符串操作、字典操作、三级菜单实例)

    字符串操作 name = "alex" print(name.capitalize()) #首字母大写 name = "my name is alex" pri ...

  8. python之最强王者(8)——字典(dictionary)

    1.Python 字典(Dictionary) 字典是另一种可变容器模型,且可存储任意类型对象. 字典的每个键值(key=>value)对用冒号(:)分割,每个对之间用逗号(,)分割,整个字典包 ...

  9. python序列,字典备忘

    初识python备忘: 序列:列表,字符串,元组len(d),d[id],del d[id],data in d函数:cmp(x,y),len(seq),list(seq)根据字符串创建列表,max( ...

  10. PowerDesigner从Sqlserver中反转为带注释的字典及快捷键操作

    PowerDesigner的操作经常忘记,所以把常用的功能记录下来备忘. 1.修改反转过来的字段 PowerDesigner从数据库反转的时候,默认不带注释,需要先进行修改. 输入如下脚本: {OWN ...

随机推荐

  1. python 2个版本如何共存

    我们在安装Python3(>=3.3)时,Python的安装包实际上在系统中安装了一个启动器py.exe,默认放置在文件夹C:\Windows\下面.这个启动器允许我们指定使用Python2还是 ...

  2. 微信公众号实现zaabix报警2017脚本(升级企业微信后)

    #!/bin/bash CropID='xxxxxxxxxxxxxxxxx' Secret='xxxxxxxxxxxxxxxx' GURL="https://qyapi.weixin.qq. ...

  3. Android--推断文本文件编码

    方法1:利用windows文本文件编码特点. windows下.Unicode.Unicode big endian和UTF-8编码的txt文件的开头会多出几个字节,各自是FF.FE(Unicode) ...

  4. HSV和HSI区别

    HSV (色相hue, 饱和度saturation, 明度value), 也称HSB (B指brightness) 是艺术家们常用的,因为与加法减法混色的术语相比,使用色相,饱和度等概念描述色彩更自然 ...

  5. poj 3653(最短路)

    题目链接:http://poj.org/problem?id=3653 思路:题目意思很简单,就是二维平面上的图,要求起点到终点的最短路.建图略坑,需要坐标映射,化二维为一维.然后就是Dijkstra ...

  6. ajax利用html5新特性带进度条上传文件

    http://blog.csdn.net/pkgray/article/details/27591283 http://www.matlus.com/html5-file-upload-with-pr ...

  7. JavaScript------如何查看var变量是否是指定类型

    function isArray(a) { //Date,Array,String,Object,Function,Boolean,Number return a.constructor.toStri ...

  8. Bootstrap组件之下拉菜单

    .dropdown--设置父元素为下拉菜单组件,向下弹出子菜单: .dropup--设置父元素为下拉菜单组件,向上弹出子菜单: .dropdown-toggle--设置button为下拉菜单切换but ...

  9. python中WSGI是什么

    uswgi学习文档 http://uwsgi-docs-cn.readthedocs.io/zh_CN/latest/WSGIquickstart.html WSGI是什么? WSGI,全称 Web ...

  10. 将json转为 SortedDictionary

     #region ConvertJsonToSortedDictionary 将json转为 SortedDictionary        /// <summary>        // ...