总结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. Launchy – 快速调出你的程序

    http://www.appinn.com/launchy/这个可是今天绝对的发现,超级好玩好用的程序,Launchy 可以使你快速的调用你电脑中的程序快捷方式,而且很智能,使用起来很智能,安装后用A ...

  2. HDU 2256 Problem of Precision (矩阵乘法)

    Problem of Precision Time Limit: 1000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Oth ...

  3. 10条建议让你创建更好的jQuery插件(转载)

    为了避免重复造轮子,自己手动开发jquery 插件,让小组其他成员可以直接使用.学习开发中,看到Phillip Senn 写的 关于jquery 插件开发注意10点,转载之! ------------ ...

  4. System V 共享内存 和 系列函数

    跟消息队列一样,共享内存也有自己的数据结构,如下: struct shmid_ds { struct ipc_perm shm_perm;    /* Ownership and permission ...

  5. 使用国内镜像源安装npm包报错

    1 使用命令安装 npm install webpack --save-dev 可能是版本太高,国内没有更新. 通过设置镜像源 npm config set registry http://regis ...

  6. 深入mysql “ON DUPLICATE KEY UPDATE” 语法的分析

    本篇文章是对mysql “ON DUPLICATE KEY UPDATE”语法进行了详细的分析介绍,需要的朋友参考下. mysql “ON DUPLICATE KEY UPDATE” 语法 如果在IN ...

  7. Java:HttpClient篇,Cookie概述,及其在HttpClient4.2中的应用

    1. Cookie 概述 Cookie是什么? Cookie 是一小段文本信息,伴随着用户请求和页面在 Web 服务器和浏览器之间传递.Cookie 包含每次用户访问站点时 Web 应用程序都可以读取 ...

  8. Android Studio项目迁移小结

    近来试着使用Android Studio.确实有些功能远远甩开eclipse几条街,可是临时用起来还不够熟练,先对这两天做项目迁移的一点心得做点总结. 这里说的项目迁移,是指从eclipse环境下的项 ...

  9. C#特性Attribute学习

    起初一直纠结于如何调用特性附着在下面那个成员的值,后来发现不需要调用,通过反射加载的时候是自动绑定上去的,即 获得成员对象之后,有一个方法可以获得特性标签. 其实从类库提供者,和类库使用者的角度,分开 ...

  10. FPGA Prototyping By Verilog Examples第五章 状态机FSM设计

    上升沿检测电路之Moore型FSM // Listing 5.3module edge_detect_moore ( input wire clk, reset, input wire level, ...