go语言map的内部实现及传参

来源:互联网 发布:软件研发过程管理 编辑:程序博客网 时间:2024/06/08 12:09

我们知道go的内置函数make返回一个Type类型的对象

func make(Type, size IntegerType) Type 

然后直接上源码:

// Builds a type representing a Hmap structure for the given map type.// Make sure this stays in sync with ../../../../runtime/hashmap.go!func hmap(t *Type) *Type {   if t.MapType().Hmap != nil {      return t.MapType().Hmap   }   bucket := mapbucket(t)   var field [8]*Field   field[0] = makefield("count", Types[TINT])   field[1] = makefield("flags", Types[TUINT8])   field[2] = makefield("B", Types[TUINT8])   field[3] = makefield("hash0", Types[TUINT32])   field[4] = makefield("buckets", Ptrto(bucket))   field[5] = makefield("oldbuckets", Ptrto(bucket))   field[6] = makefield("nevacuate", Types[TUINTPTR])   field[7] = makefield("overflow", Types[TUNSAFEPTR])   h := typ(TSTRUCT)   h.Noalg = true   h.Local = t.Local   h.SetFields(field[:])   dowidth(h)   t.MapType().Hmap = h   h.StructType().Map = t   return h}
// MapType contains Type fields specific to maps.type MapType struct {   Key *Type // Key type   Val *Type // Val (elem) type   Bucket *Type // internal struct type representing a hash bucket   Hmap   *Type // internal struct type representing the Hmap (map header object)   Hiter  *Type // internal struct type representing hash iterator state}// MapType returns t's extra map-specific fields.func (t *Type) MapType() *MapType {   t.wantEtype(TMAP)   return t.Extra.(*MapType)}
// A header for a Go map.type hmap struct {   // Note: the format of the Hmap is encoded in ../../cmd/internal/gc/reflect.go and   // ../reflect/type.go. Don't change this structure without also changing that code!   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)   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)   // If both key and value do not contain pointers and are inline, then we mark bucket   // type as containing no pointers. This avoids scanning such maps.   // However, bmap.overflow is a pointer. In order to keep overflow buckets   // alive, we store pointers to all overflow buckets in hmap.overflow.   // Overflow is used only if key and value do not contain pointers.   // overflow[0] contains overflow buckets for hmap.buckets.   // overflow[1] contains overflow buckets for hmap.oldbuckets.   // The first indirection allows us to reduce static size of hmap.   // The second indirection allows to store a pointer to the slice in hiter.   overflow *[2]*[]*bmap}

func hashGrow(t *maptype, h *hmap) {   if h.oldbuckets != nil {      throw("evacuation not done in time")   }   oldbuckets := h.buckets   newbuckets := newarray(t.bucket, 1<<(h.B+1))   flags := h.flags &^ (iterator | oldIterator)   if h.flags&iterator != 0 {      flags |= oldIterator   }   // commit the grow (atomic wrt gc)   h.B++   h.flags = flags   h.oldbuckets = oldbuckets   h.buckets = newbuckets   h.nevacuate = 0   if h.overflow != nil {      // Promote current overflow buckets to the old generation.      if h.overflow[1] != nil {         throw("overflow is not nil")      }      h.overflow[1] = h.overflow[0]      h.overflow[0] = nil   }   // the actual copying of the hash table data is done incrementally   // by growWork() and evacuate().}

源码解析:
对于map类型Type实例中,包含一个MapType结构指针,而MapType中包含了Hmap结构指针,
Hmap指向一个hmap结构体,该结构体中的buckets和oldbuckets对应着真实的key/value数据,map重新分桶时,
buckets改变,但hmap的地址不会改变
图示:
Type{  //A实例             
Hmap *Type //指向hmap
}
                                     //hmap在make时才会生成
                                   type hmap struct {
map实例A传参后,                       buckets    unsafe.Pointer ----------->  类型数(实际数据key/value)
在函数内得到A的拷贝实例B               oldbuckets unsafe.Pointer                              
                                   }
Type{ //B实例
Hmap *Type  //指向A指向的hmap
}





原创粉丝点击