Map的声明
- 使用
make()
函数定义Map
go
map_name := make(map[KeyType]valueType,initialCapacity)
KeyType是键的类型,ValueType是值的类型,initialCapacity是可选参数,用于指定map的初始容量。
- 使用
map
关键字定义Map
go
m := map[string]int {
"apple": 1,
"banana": 2,
}
Map的基本操作
- 获取元素
go
//获取键值对
v1 := m["apple"]
v2, ok := m["pear"] //如果键不存在, ok的值为false,v2的值为该类型的零值
- 修改元素
go
//修改键值对
m["apple"]=5
- 获取Map的长度
go
//获取Map的长度
len := len(m)
- 遍历Map
go
for k, v := range m {
fmt.Println("%s, %d\n",k, v)
}
- 删除元素
go
delete(m, "banana")
注意:若该元素不存在于指定map,delete函数也不会报错,也不会有任何影响
Go-Map使用心得及注意事项
1. 不支持并发操作(非线程安全)
当多个线程操作同一个map时,会引发线程并发,并报错fatal error: concurrent map read and map write
如何解决这个问题?
1. sync.Mutex
当存在线程正在对map进行读写的时候,不允许其他线程进入map进行读写,让其在外面等待,直到正在读写的线程操作完毕。
go
package main
import (
"fmt"
"sync"
)
func main() {
// 创建一个包含键值对的map
myMap := make(map[string]int)
// 创建一个互斥锁
var mu sync.Mutex
// 开启多个goroutine并发写入map
for i := 0; i < 10; i++ {
go func() {
// 对map加锁
mu.Lock()
defer mu.Unlock()
// 向map中写入数据
myMap["key"] = myMap["key"] + 1
}()
}
// 等待所有goroutine执行完成
for i := 0; i < 10; i++ {
go func() {
// 对map加锁
mu.Lock()
defer mu.Unlock()
// 从map中读取数据
fmt.Println(myMap["key"])
}()
}
// 等待一段时间,确保所有goroutine执行完成
time.Sleep(time.Second)
}
线程的每次对map进行读写前对map进行加锁,当操作完成后解锁,这样就避免了并发问题。
缺点:读写性能低。每次进行读写操作都需要对整个map进行加锁,锁的颗粒度相当大。如果出现两个线程操作的map的不同区域,互不影响,完全可以将锁的颗粒度减少为线程当前需要操作的区域,这样就能大大提高读写效率。
2. sync.Map
在 Golang 中,sync.Map 是一个并发安全的 Map 实现,可以在多个 Goroutine 中安全地读写 Map。
go
package main
import (
"fmt"
"sync"
)
func main() {
m := sync.Map{}
var wg sync.WaitGroup
wg.Add(2)
go func() {
defer wg.Done()
m.Store("key1", "value1")
}()
go func() {
defer wg.Done()
value, _ := m.Load("key1")
fmt.Printf("Value of key1: %v\n", value)
}()
wg.Wait()
}
缺点:
- 使用较为复杂。value类型是一个interface{},需要断言使用。
- 适用读多写少的场景。读写分离的实现方式,在读多写少的场景性能优越,但是写多的场景中,读操作命中率低,需要不断同步读写map,性能降低。
2. map的初始化
map的使用需要先初始化。
如果只是定义了map而没有进行初始化,对map进行写操作会报错,因为map此时为nil。
- 写操作:报错
panic: assignment to entry in nil map
但是可以进行读操作,获取某一个值,返回的是value类型的默认值。
3. key的类型
go中,map的key不支持func、slice、map这三种类型。
4. map本身为一个引用数据类型(指针)
map在程序中是一个指针类型的,传参过程中,实参和形参指的是同一个实体。