总结golang之map

2017年04月13日 23:35:53 趁年轻造起来 阅读数:18637 标签: golangmapgo 更多

个人分类: golang
 
版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/Soooooooo8/article/details/70163475

0x01 map基本操作

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34

0x02 map键类型

支持 == 操作符的类型有:

  • boolean,
  • numeric,
  • string,
  • pointer,
  • channel,
  • interface(as long as dynamic type supports equality),
  • 以及只包含上述类型的array和struct

不支持 == 操作符的类型有:

  • slice,
  • map,
  • func,

补充

  1. 不像Java可以为class自定义hashcode方法,以及C++可以重载==操作符,golang map**不支持**==重载或者使用自定义的hash方法。因此,如果想要把struct用作map的key,就必须保证struct不包含slice, map, func
  2. golang为uint32、uint64、string提供了fast access,使用这些类型作为key可以提高map访问速度,详见hashmap_fast.go

0x03 map并发

map不是并发安全的,通常使用sync.RWMutex保护并发map

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13

0x04 map小技巧

4.1. 利用value类型的零值

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12

4.2. map[k1]map[k2]v 对比 map[struct{k1, k2}]v

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21

0x05 map实现细节浅析

5.1. 如何计算hash值

golang为每个类型定义了类型描述器_type,并实现了hashable类型的_type.alg.hash_type.alg.equal

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8

5.2. map实现结构

map的实现主要有三个struct,

  1. maptype用来保存map的类型信息,包括key、elem(value)的类型描述器,keysize,valuesize,bucketsize等;
  2. hmap - A header for a Go map. hmap保存了map的实例信息,包括count,buckets,oldbuckets等;buckets是bucket的首地址,用hash值的低h.B位hash & (uintptr(1)<<h.B - 1)计算出key所在bucket的index; 
  3. bmap - A bucket for a go map. bmap只有一个域tophash [bucketCnt]uint8,它保存了key的hash值的高8位uint8(hash >> (sys.PtrSize*8 - 8));一个bucket包括一个bmap(tophash数组),紧跟的bucketCnt个keys和bucketCnt个values,以及一个overfolw指针。 

makemap根据maptype中的信息初始化hmap

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16

5.3. 如何访问map

golang的maptype保存了key的类型描述器,以供访问map时调用key.alg.hashkey.alg.equal

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42

5.4. map扩张

这部分留待以后有机会再续。这里暂时附上Keith Randall的slide作为参考。 

0x06 map建议

  • 如果知道size,预先分配资源make(map[int]int, 1000)
  • uint32, uint64, string作为键,非常快
  • 清理map:for k:= range m { delete(m, k) }
  • key和value中没有指针可以使GC scanning更快

总结golang之map的更多相关文章

  1. Golang中map的三种声明方式和简单实现增删改查

    package main import ( "fmt" ) func main() { test3 := map[string]string{ "one": & ...

  2. golang 中 map 转 struct

    golang 中 map 转 struct package main import ( "fmt" "github.com/goinggo/mapstructure&qu ...

  3. golang之map的使用声明

    1.map的基本介绍 map是key-value数据结构,又称为字段或者关联数组.类似其它编程语言的集合,在编程中是经常使用到的 2.map的声明 1)基本语法 var map 变量名 map[key ...

  4. Golang:sync.Map

    由于map在gorountine 上不是安全的,所以在大量并发读写的时候,会出现错误. 在1.9版的时候golang推出了sync.Map. sync.Map 通过阅读源码我们发现sync.Map是通 ...

  5. golang中map原理剖析

    1. golang中的map有自己的一套实现原理,其核心是由hmap和bmap两个结构体实现的 2.  初始化map package main func main() { // 初始化一个可容纳10个 ...

  6. golang笔记——map

    通过 new 创建的引用类型对象是不完整创建,比如 map,它仅分配了字典类型本身所需的内存(指针包装),而没有分配键值存储内存,也没有初始化散列桶等内部属性,因此无法工作,如下代码就是错误的: p ...

  7. 【GoLang】GoLang 遍历 map、slice、array方法

    代码示例: map1 := make(map[string]string) map1["a"] = "AAA" map1["b"] = &q ...

  8. Golang 嵌套map赋值办法

    http://my.oschina.net/sol/blog/159060 m := map[string]map[string]string{} mm, ok := m["kkk" ...

  9. golang的map

    map--字典 map的基本使用: package main import "fmt" // 先声明 type PersonInfo struct { id string name ...

随机推荐

  1. javascript高级程序设计第二章

    看后总结: 1.js代码用得最多的两种加载方式: a)外部文件形式:<script type="text/javascript" src="jquery.min.j ...

  2. 简述Android触摸屏手势识别

    很多时候,利用触摸屏的Fling.Scroll等Gesture(手势)操作来操作会使得应用程序的用户体验大大提升,比如用Scroll手势在 浏览器中滚屏,用Fling在阅读器中翻页等.在Android ...

  3. Linux命令-防火墙命令:iptables

    iptables详解--转 查看防火墙设置: 第一种方式: cat /etc/sysconfig/iptables 第二种方式: iptables -L -n -v 设置防火墙: 第一种方式: ipt ...

  4. JFinal record类型数据在前台获取

    1.jfinal record还得自己处理一下 可以使用 this.setSessionAttr("user", record.getColumns()); 这样在jsp中el表达 ...

  5. IIS下浏览指定文件(如:web.config)

    具体步骤如下: 1.快捷键:Ctrl + R 2.输入:%windir%\System32\inetsrv\config\applicationHost.config 3.注销:fileExtensi ...

  6. WIN7下恼人的AppData——删除没用的缓存文件

    今日.打开电脑,发现C盘可用容量居然变得非常小.认为非常是可疑,例如以下图所看到的: 最初的反应是电脑中毒了,于是使用360卫士.360杀毒对C盘查杀,由于明明记得C盘有40多G的可用空间才对.出现这 ...

  7. C#--类之隐藏基类的成员

    using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.T ...

  8. python标准库介绍——21 UserDict 模块详解

    ==UserDict 模块== ``UserDict`` 模块包含了一个可继承的字典类 (事实上是对内建字典类型的 Python 封装). [Example 2-15 #eg-2-15] 展示了一个增 ...

  9. Xilinx全局时钟

    前言 Xilinx系列.ISE环境中,设计复杂工程时全局时钟系统的设计显得尤为重要. 一.时钟网络与全局缓冲 在XilinxFPGA中,时钟网络分为两类:全局时钟网络和I/O区域时钟网络.以全铜工艺实 ...

  10. unity5, Configurable Joint: Anchor, Connected Anchor, Auto Configure Connected Anchor

    configurable joint加在轮子上,connected body是车身. 这种情况下,Anchor=(0,0,0)表示轮子一端joint锚点取carWheelCenter Connecte ...