什么是map?
map是一個可以存儲key/value對的一種數據結構,map像slice一樣是引用類型,map內部實現是一個hash table,因此在map中存入的數據是無序的(map內部實現)。而每次從map中讀取的數據也是無序的,因為golang在設計之初,map迭代器的順序就是隨機的,有別于C/C++,雖然存入map的數據是無序的,但是每次從map中讀取的數據是一樣的(為什么每次讀取順序不一樣)。
聲明和初始化
// 聲明一個map,因為map是引用類型,所以m是nil
var m map[KeyType]ValueType
// 初始化方式一,空map,空并不是nil
m := map[KeyType]ValueType{}
//初始化方式二,兩種初始化的方式是等價的
m := make(map[KeyType]ValueType)
基本操作
m := map[string]int{}
// 增加一個key/value對
m["Tony"] = 10
// 刪除Key Tony
delete(m, "Tony")
// 修改Key Tony的值
m["Tony"] = 20
// 判斷某個Key是否存在
if _, ok := m["Tony"]; ok {
fmt.Println("Tony is exists")
}
// 遍歷map
for key, value := range m {
fmt.Printf("Key = %s, Value = %d", key, value)
}
// 使用多個值對map進行初始化
mp := map[string]int {
"Tina": 10,
"Divad": 20,
"Tom": 5,
}
Key和Value可以使用什么類型?
Key :只要是可比較(可以使用==進行比較,兩邊的操作數可以相互賦值)的類型就可以,像整形,字符串類型,浮點型,數組(必須類型相同);而map,slice和function不能作為Key的類型。
Value :任何類型都可以。
map中關于Key和Value類型參考
對map進行并發訪問時需增加同步機制
map在并發訪問中使用不安全,因為不清楚當同時對map進行讀寫的時候會發生什么,如果像通過goroutine進行并發訪問,則需要一種同步機制來保證訪問數據的安全性。一種方式是使用sync.RWMutex
。
// 通過匿名結構體聲明了一個變量counter,變量中包含了map和sync.RWMutex
var counter = struct{
sync.RWMutex
m map[string]int
}{m: make(map[string]int)}
// 讀取數據的時候使用讀鎖
counter.RLock()
n := counter.m["Tony"]
counter.RUnlock()
// 寫數據的使用使用寫鎖
counter.Lock()
counter.m["Tony"]++
counter.Unlock()