Map

哈希表是无序的key/value对集合,检索、更新、删除的时间复杂度为O(1)

类型

map类型的写法为:map[key]value

key的类型相同,value的类型也相同。

key必须是支持 == 比较运算符的数据类型,用浮点类型做key是坏的想法。

语法

  • 创建

    可以直接创建nil值的map:

    var ages map[string]int

    可以使用make创建map:

    ages := make(map[string]int)

    还可以使用字面值语法创建map:

    ages := map[string]int{
        "alice": 31,
        "charlie": 34,
    }
    // 这相当于
    // ages := make(map[string]int)
    // ages["alice"] = 31
    // ages["charlie"] = 34
  • 访问

    可以使用下标访问:

    ages["alice"] = 32

    如果查找失败,将返回value类型的零值。

    简短复制语法可以用在map上:

    ages["bob"] += 1
    // ages["bob"]++

    禁止对map中的元素进行取地址操作,map可能随着元素数量的增长重新分配内存空间,从而可能导致之前的地址无效。

  • 删除

    可以使用delete函数删除

    delete(ages, "alice")
  • 遍历

    可以使用range风格的for循环实现:

    for name, age := range ages {
        fmt.Println(name, age)
    }

    遍历的顺序是随机的,如果想顺序遍历key/value对,必须显示对key进行排序,可以使用sort包的Strings函数对字符串slice进行排序。

    names := []string{}
    for name := range ages {
        names = append(names, name)
    }
    sort.Strings(names)
    for _, name := range names {
        fmt.Println(ages[name])
    }
  • 零值

    map类型的零值是nil

    查找、删除、lenrange都可以安全工作在nil值的map上,但是向一个nil值的map存入元素将导致一个panic异常。

  • 检查元素是否存在

    if age, ok := ages["bob"]; !ok { /*...*/ }
  • 比较

    只可以与nil进行比较操作。

    如果要判断两个map是否相同:

    func equal(x, y map[string]int) bool {
        if len(x) != len(y) {
            return false
        }
    
        for k, xv := range x {
            if yv, ok := y[k]; !ok || yv != xv {
                return false
            }
        }
        return true
    }

Last updated

Was this helpful?