Go语言中的`map`

3 阅读3分钟

一、map的基本概念

  1. 定义
    • 在Go语言中,map是一种无序的键 - 值对(key - value pairs)集合。它就像是一个字典,通过键(key)来快速查找和访问对应的值(value)。键是唯一的,在一个map中不能有两个相同的键,但不同的键可以对应相同的值。
  2. 语法格式
    • 定义一个map的基本语法是map[keyType]valueType。其中,keyType是键的数据类型,valueType是值的数据类型。例如,m := map[string]int{"apple": 1, "banana": 2}定义了一个键为字符串类型、值为整数类型的map,并初始化了两个键 - 值对。

二、map的初始化

  1. 使用字面量初始化
    • 可以在定义map时使用字面量来初始化键 - 值对。如上面的例子m := map[string]int{"apple": 1, "banana": 2},使用花括号{}包含键 - 值对,键和值之间用冒号:分隔。
    • 如果要创建一个空的map,可以写成m := map[string]int{}
  2. 使用make函数初始化
    • 另一种初始化map的方式是使用make函数。例如,m := make(map[string]int)创建了一个键为字符串类型、值为整数类型的空map
    • make函数还可以指定map的初始容量。例如,m := make(map[string]int, 10)创建了一个初始容量为10的map,这在预先知道map大致规模的情况下可以提高性能,因为当map需要扩容时会消耗一定的性能。

三、map的数据访问

  1. 读取值
    • 通过键来读取map中的值。例如,对于m := map[string]int{"apple": 1, "banana": 2},可以使用value := m["apple"]来获取键"apple"对应的值,此时value的值为1
    • 如果访问的键不存在,会返回值类型的零值。例如,对于上面的mvalue := m["cherry"],因为"cherry"这个键不存在,所以value的值为0(因为value的类型是intint类型的零值是0)。
  2. 检查键是否存在
    • 可以使用双值赋值的方式来检查键是否存在并获取值。例如,value, ok := m["cherry"],这里ok是一个布尔值,如果键存在,oktruevalue为对应的值;如果键不存在,okfalsevalue为值类型的零值。
  3. 修改值
    • 通过键来修改map中的值。例如,对于m := map[string]int{"apple": 1, "banana": 2},可以使用m["apple"] = 3来将键"apple"对应的值修改为3

四、map的遍历

  1. 基本遍历方式
    • 可以使用for range循环来遍历map。由于map是无序的,每次遍历的顺序可能不同。例如:
    m := map[string]int{"apple": 1, "banana": 2}
    for key, value := range m {
        fmt.Printf("Key: %s, Value: %d\n", key, value)
    }
    
    • 这个循环会遍历m中的所有键 - 值对,每次迭代将键赋值给key,值赋值给value,然后打印出来。

五、map的元素添加和删除

  1. 添加元素
    • map中添加元素就像修改元素一样,通过指定一个不存在的键并赋值来添加。例如,m := make(map[string]int)m["cherry"] = 3就向map中添加了一个新的键 - 值对{"cherry": 3}
  2. 删除元素
    • 使用delete函数来删除map中的元素。例如,对于m := map[string]int{"apple": 1, "banana": 2},可以使用delete(m, "apple")来删除键为"apple"的元素,之后m中就不再包含"apple"这个键的键 - 值对了。

六、map的注意事项

  1. 键的类型限制
    • 作为map的键,其类型必须是可比较的。这意味着像切片(slice)、函数(function)和包含切片的结构体等不能作为map的键,因为它们是不可比较的。但是整数、字符串、布尔值、数组(元素类型是可比较的)等可以作为键。
  2. 并发安全性
    • 标准的map在多个goroutine同时读写时是不安全的。如果需要在并发环境下安全地使用map,可以使用sync.Map(来自sync包),它提供了在多个goroutine之间安全地读写map的功能。