初窥:golang 中 map实现与使用

本文深入探讨了Go语言中的Map,讲解了Map的key类型限制,指出只有可比较类型才能作为key。同时,揭示了Map的内部实现是一个哈希表,详细阐述了其数据结构hmap,包括count、flags、B、noverflow等字段的作用。此外,还介绍了map的扩展知识,如哈希冲突的解决和Map的动态增长策略。
摘要由CSDN通过智能技术生成

1. map基础

1.1. key类型限制

在golang中,map的key必须是可以支持==比较的数据类型:

  • 可以比较:bool、integer、float1 、string、指针、channel2 、interface3 、array、structure4
  • 不可比较:slice、map、func

2. map深入

2.1. map的原理

golang的map是一个hash表,利用拉链法解决哈希冲突,map底层数据结构由一个结构体hmap实现:

// A header for a Go map.
type hmap struct {
	// Note: the format of the hmap is also encoded in cmd/compile/internal/reflectdata/reflect.go.
	// Make sure this stays in sync with the compiler's definition.
	count     int // # live cells == size of map.  Must be first (used by len() builtin)
	flags     uint8
	B         uint8  // log_2 of # of buckets (can hold up to loadFactor * 2^B items)
	noverflow uint16 // approximate number of overflow buckets; see incrnoverflow for details
	hash0     uint32 // hash seed

	buckets    unsafe.Pointer // array of 2^B Buckets. may be nil if count==0.
	oldbuckets unsafe.Pointer // previous bucket array of half the size, non-nil only when growing
	nevacuate  uintptr        // progress counter for evacuation (buckets less than this have been evacuated)

	extra *mapextra // optional fields
}
  • count: map元素数量
  • flags: map当前状态标志
const(
	// ...
	// flags
	iterator     = 1 // there may be an iterator using buckets
	oldIterator  = 2 // there may be an iterator using oldbuckets
	hashWriting  = 4 // a goroutine is writing to the map
	sameSizeGrow = 8 // the current map growth is to a new map of the same size
	// ...
)
  • B: bucket 数量的对数, N ( b u c k e t ) = 2 B N(bucket)=2^{B} N(bucket)=2B
  • noverflow: 出现溢出的 bucket 的数量的估计值
  • hash0: 哈希种子
  • buckets: bucket 数组指针
  • oldbuckets: 旧 bucket 数组指针
  • nevacuate: 迁移进度
  • extra: …

  1. float的比较是不安全的 ↩︎

  2. channel的比较在于其存储的指针,指向同一处的channel才相等 ↩︎

  3. interface比较结果为true的条件是其断言类型相等并且对应类型实体的成员变量值相等 ↩︎

  4. 要想structure是可以比较的,其成员变量也必须是可以比较的,结构体比较为true的条件是类型和成员变量值均相等 ↩︎

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值