go学习笔记(映射)

映射

映射是一种用来存储一系列无序键值对的数据结构

  1. 映射的底层存储结构。
image-20200105143952464.png
// A header for a Go map.
type hmap struct {
    // Note: the format of the hmap is also encoded in cmd/compile/internal/gc/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
}

// mapextra holds fields that are not present on all maps.
type mapextra struct {
    // If both key and elem 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.extra.overflow and hmap.extra.oldoverflow.
    // overflow and oldoverflow are only used if key and elem do not contain pointers.
    // overflow contains overflow buckets for hmap.buckets.
    // oldoverflow contains overflow buckets for hmap.oldbuckets.
    // The indirection allows to store a pointer to the slice in hiter.
    overflow    *[]*bmap
    oldoverflow *[]*bmap

    // nextOverflow holds a pointer to a free overflow bucket.
    nextOverflow *bmap
}

// A bucket for a Go map.
type bmap struct {
    // tophash generally contains the top byte of the hash value
    // for each key in this bucket. If tophash[0] < minTopHash,
    // tophash[0] is a bucket evacuation state instead.
    tophash [bucketCnt]uint8
    // Followed by bucketCnt keys and then bucketCnt elems.
    // NOTE: packing all the keys together and then all the elems together makes the
    // code a bit more complicated than alternating key/elem/key/elem/... but it allows
    // us to eliminate padding which would be needed for, e.g., map[int64]int8.
    // Followed by an overflow pointer.
}

可以看出一个映射里包含了很多个hash桶(bucket),每个桶里存储了hash值的高8位以及8个key和8个value,key的hash值的低8位确定key在桶里的位置。每次查找,删除键值对的时候都把需要把key传给hash函数,由hash函数生成一个索引,这个索引最终将键值对分布到所有可用的桶里,具体的底层数据结构另说。

  1. 创建初始化使用
dict := make(map[string]int) //make函数创建一个无须集合。
dict := map[string][int]{"chujiu":20,"dong":30} //字面量初始化一个映射
dict1 := map[string][int]{}//初始化一个空的map
dict := map[[]string]int{} //这会抛出一个错误,map的key理论上可以用任何类型作为key,但有引用类型除外,基本上可以做==等值比较的类型都可以作为key,这里用切片作为key是不行的,引用,函数,包含切片的结构类型都不行。
//Invalid map key type: the comparison operators == and != must be fully defined for key type

var dict2 map[string]int //声明一个为nil的映射,这和空的映射并不相等。也不能赋值
dict2["age"] = 2 //针对nil的映射存储值会发生一个panic错误。 assignment to entry in nil map
dict1["age"] = 2 //这个是可以的,初始化的时候是一个空的映射。
dict2 = dict1 //这样也是可以的。但这是一个引用操作,对dict2操作任何修改dict1都会受到影响。因为指向的是同一个bucket数组。

//从映射中取出一个值来,即使这个key不存在,也会返回一个对应的零值。
value := dict1["num"] //即使key不存在,value也会返回一个0
if value == 0 {
  fmt.Print(value)
}
for key, value := range dict1 {
  fmt.Println("key:"+key, ",value:", value)
}

delete(dict1, "age")//删除一个映射中的key,没有返回值,函数间传递是引用传递,并不会拷贝一个新的映射集合,也就是当在函数内部对映射做出了修改后,原来的映射也会受到影响。
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 216,240评论 6 498
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 92,328评论 3 392
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 162,182评论 0 353
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,121评论 1 292
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,135评论 6 388
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,093评论 1 295
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,013评论 3 417
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,854评论 0 273
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,295评论 1 310
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,513评论 2 332
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,678评论 1 348
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,398评论 5 343
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,989评论 3 325
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,636评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,801评论 1 268
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,657评论 2 368
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,558评论 2 352

推荐阅读更多精彩内容

  • 这只小狗是我们家自己养的一只小狗。叫小黄,因为它的毛是黄色的小狗。它很可爱,它玩耍时候可爱,它吃饭的时候也很可爱。...
    毓晶阅读 355评论 0 0
  • 在我的印象里八五后开始留守儿童就越来越多,我当年也算半个留守儿童,妈妈常年在外务工,爸爸带着我和弟弟在家,童年...
    春天里的宁静阅读 502评论 0 0
  • 我们都曾爱过一个最好的人,区别在于有人留下来,而有人越走越远,我属于后者。 那个人已经远到连空气中都没了痕迹。可即...
    女子爱红妆阅读 2,371评论 0 0
  • 你们会不会像我一样,故意把自己那么伤的样子。 很累,不知道自己在做什么,故意远离别人,故意不让别人接近。 知道这个...
    初之心阅读 167评论 0 0
  • emmmm,最近不顺心的事一大堆,好像和快乐一样什么都是成双成对的。在恐惧和气愤之后,我也在反思自己的问题。你看人...
    初见_86a6阅读 163评论 0 0