map字典

周杰伦是李小莹的男神 · · 827 次点击 · · 开始浏览    
这是一个创建于 的文章,其中的信息可能已经有所发展或是发生改变。

golang的map实现并不是像c++一样使用红黑树,而是使用了hashmap,用数组来实现。

map 是字典的概念,它的格为 map[keyType]valueType” 。 map 的读取和设置也类似 slice 一样,通过 key 来操作,只是 slice 的index 只能是`int`类型,而 map 多了很多类型,可以是 int ,可以是 string及所有完全定义了 == 与 != 操作的类型。


// 1. 声明    var m map[string]int 

// 2. 初始化,声明之后必须初始化才能使用,向未初始化的map赋值引起 panic: assign to entry in nil map.

    m = make(map[string]int)

    m = map[string]int{}

// 1&2. 声明并初始化

    m := make(map[string]int)

    m := map[string]int{}

// 3. 增删改查

    m["route"] = 66

    delete(m, "route")  // 如果key不存在什么都不做

    i := m["route"]  // 三种查询方式,如果key不存在返回value类型的零值

    i, ok := m["route"]

    _, ok := m["route"]

// 4. 迭代(顺序不确定

    for k, v := range m {

        use(k, v)

    }

// 5. 有序迭代

    import "sort"

    var keys []string

    for k, _ := range m {

        keys = append(keys, k)

    }

    sort.Strings(keys)

    for _, k := range keys {

        use(k, m[k]

    }


那为什么golang的map是安全的呢,从源码来看,golang的map使用了桶的概念,元素是被hash到桶存储,每个桶预设是存储八个k,v,而且在头部有一个uint8 tophash[8]的结构,存储每个key的高八位(即hash(key) » (64 - 8)),如果该位置未被放置元素,则有一个特殊的标志Empty。在插入删除的时候,首先会比较该uint8跟hash(key)是否相等。当然,桶还利用了overflow指针,可以无限的增长,类似链表。所以,for循环其实是对每个桶进行迭代,判断每个uint8位置,删除操作也并不是实际的memset,而是把对应的tophash的位置置为Empty.因此,在迭代golang的map过程中,使用delete是安全的。


有疑问加站长微信联系(非本文作者)

本文来自:简书

感谢作者:周杰伦是李小莹的男神

查看原文:map字典

入群交流(和以上内容无关):加入Go大咖交流群,或添加微信:liuxiaoyan-s 备注:入群;或加QQ群:692541889

827 次点击  
加入收藏 微博
1 回复  |  直到 2018-09-21 11:41:02
暂无回复
添加一条新回复 (您需要 登录 后才能回复 没有账号 ?)
  • 请尽量让自己的回复能够对别人有帮助
  • 支持 Markdown 格式, **粗体**、~~删除线~~、`单行代码`
  • 支持 @ 本站用户;支持表情(输入 : 提示),见 Emoji cheat sheet
  • 图片支持拖拽、截图粘贴等方式上传