map是go语言中内置的字典类型,存储的是key:value键值对类型的数据。map通过key访问数据。
map特点
map是无序的、长度不固定、不能通过下标获取,只能通过key来访问。map的长度不固定,可以通过内置函数len(map)来获取map的长度。- 创建
map的时候也是通过make函数创建。 map的key是唯一的,不能重复,如果重复,新增加的回复改之前的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.map的map,它解决了并发过程中,读写数据不安全的问题。此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