1. map简介
在Go语言中,map是一个很有用的数据类型。map是一个无序键值对的集合,其中所有的键和所有的值都可以是任意类型。通过键可以在map中查找对应的值。类似于Python中的字典,Java中的HashMap。
使用make()创建map
m := make(map[string]int)
上述代码创建了一个键的类型为string,值的类型为int的空map。
2. map赋值与获取
2.1 赋值
map可以使用下标语法进行赋值,也可以使用内置的delete()函数删除某个键值对。
m := make(map[string]int)
m["apple"] = 1
m["banana"] = 2
delete(m, "apple")
2.2 获取
可以通过下标语法获取map中对应键的值,如果该键不存在,则返回值类型的默认值。
m := make(map[string]int)
fmt.Println(m["apple"]) // 输出0,因为"apple"键不存在于m中
3. map遍历
Go语言中的for...range语句可以用于遍历数组、切片、字符串、map和通道。遍历map时,每次迭代返回两个值,第一个是键,第二个是键对应的值。
m := map[string]int{"apple": 1,
"banana": 2,
"orange": 3}
for k, v := range m {
fmt.Printf("key=%s, value=%d", k, v)
}
输出:
key=apple, value=1
key=banana, value=2
key=orange, value=3
4. map的长度与判断key是否存在
可以使用len()函数获取map的长度,也可以使用下标语法来判断某个键是否存在于map中。
m := map[string]int{"apple": 1}
fmt.Println(len(m)) // 输出1
if _, ok := m["apple"]; ok {
fmt.Println("该键存在于map中")
}
5. map的值为切片
在实际使用中,我们可以将map的值定义为切片类型,以便于在同一键下存储多个值。
m := make(map[string][]int)
m["apple"] = []int{1, 2, 3}
m["banana"] = []int{4, 5, 6}
fmt.Println(m["apple"]) // 输出[1 2 3]
6. map的并发访问
在并发环境下,多个goroutine可能会同时对同一个map进行读写操作,如果不进行任何保护,会产生数据竞争问题。Go语言提供了sync包中的Map类型来解决这个问题。
sync.Map是Go1.9引入的新类型,它是并发安全的,可以在多个goroutine中安全地读写。它的读操作不需要加锁,写操作需要加锁。
var m sync.Map
m.Store("apple", 1)
value, ok := m.Load("apple")
fmt.Println(value, ok)
m.Delete("apple")
注意: 对sync.Map类型进行集合的操作时,需要使用sync.Map自带的方法,而不能使用常规的map[]操作。
7. 小结
map是一个无序键值对的集合,可以使用make()创建,可以使用下标语法赋值和获取值,可以使用for...range语句遍历,可以使用len()函数获取长度,也可以使用sync.Map实现并发安全的访问。