mapgo语言中内置的字典类型,存储的是key:value键值对类型的数据。map通过key访问数据。

map特点

  • map是无序的、长度不固定、不能通过下标获取,只能通过key来访问。
  • map的长度不固定,可以通过内置函数len(map)来获取map的长度。
  • 创建map的时候也是通过make函数创建。
  • mapkey是唯一的,不能重复,如果重复,新增加的回复改之前的key值。
// 声明map 默认值是 nil
var m1 map[string]int
// 声明 变量名称 map[key类型]value类型

// 使用make声明
m2 := make(map[string]int)

// 直接声明并初始化赋值map方法
m3 := map[string]int{"a": 1, "b": 2}

map的使用

map是引用类型,如果声明了但是没有初始化值,默认是nil。空的切片是可以直接使用的,切片底层使用的数组,但是空的map不能直接使用。需要先make之后才能使用。

var m1 map[string]int

// 使用make声明
m2 := make(map[string]int)

// 直接声明并初始化赋值map方法
m3 := map[string]int{"a": 1, "b": 2}

fmt.Println(m1 == nil) // true
fmt.Println(m2 == nil) // false
fmt.Println(m3 == nil) // false

// map为 nil的时候不能使用,所以使用之前先判断是否为nil
if m1 == nil {
    m1 = make(map[string]int)
}

// 操作map
m1["a"] = 1
m1["b"] = 2

// 获取map属性
val := m1["a"]
fmt.Println(val) // 1

// 判断key是否存在
val, ok1 := m1["b"]
val, ok2 := m1["c"]
fmt.Println(val, ok1) // 2 true
fmt.Println(val, ok2) // 0 false

// 修改map
m1["a"] = 3
fmt.Println(m1["a"]) // 3

// 删除map中key值对应的数据
delete(m1, "a")
fmt.Println(m1) // map[b:2]

// 获取map总长度
fmt.Println(len(m1)) // 1

map的遍历

// 初始化map
map1 := make(map[string]int)
map1["a"] = 1
map1["b"] = 2
map1["c"] = 3
map1["d"] = 4

// 遍历map
for key, value := range map1 {
    fmt.Println(key, value)
}

输出

b 2
c 3
d 4
a 1

因为map是无序的,所以,遍历输出顺序也是乱的。

map结合slice

map1 := make(map[string]int)
map1["a"] = 1
map1["b"] = 2
map1["c"] = 3
map1["d"] = 4

map2 := make(map[string]int)
map2["a"] = 10
map2["b"] = 20
map2["c"] = 30
map2["d"] = 40

// 将map存入切片
s1 := make([]map[string]int, 0, 2)
s1 = append(s1, map1)
s1 = append(s1, map2)

// 遍历切片
for key, value := range s1 {
    fmt.Println(key, value)
}

输出

0 map[a:1 b:2 c:3 d:4]
1 map[a:10 b:20 c:30 d:40]

sync.map的使用

map在并发编程中,读取数据是安全的,读写操作时则是不安全的。在go 1.9版本后,内置了一种sync.mapmap,它解决了并发过程中,读写数据不安全的问题。此map需要使用特有方法操作数据。

package main

import (
    "fmt"
    "sync"
)

var syncmap sync.Map

func main() {

    // Store方法将键值对保存到sync.map中
    syncmap.Store("a", 1)
    syncmap.Store("b", 2)
    syncmap.Store("c", 3)

    // Load方法获取sync.Map 键对应的值
    fmt.Println(syncmap.Load("a")) // 1 true

    // Delete方法删除对应键值对
    syncmap.Delete("a")

    // Range遍历所有sync.Map中的键值对
    syncmap.Range(func(key, value interface{}) bool {
        fmt.Println(key, value)
        return true
    })
}

输出

1 true
b 2
c 3
Last modification:November 14, 2022
If you think my article is useful to you, please feel free to appreciate