一、map实现原理
1、Go中的map在底层是用哈希表实现,一个hashmap的关键元素包括:hash函数,冲突解决方式。go的冲突解决方法属于链表法的一种。 hash函数为模运算
2、map不是goroutine安全的,所以在有多个gorountine对map进行写操作是会panic。多gorountine读写map是应加锁(RWMutex),或使用sync.Map
3、内存布局
二、map使用陷阱
map 只有 len操作, 没有 cap 操作: Map Capacity
错误:
package main
import (
"fmt"
)
func main() {
m := map[int]string{1: "a", 2: "b", 3: "c"}
cap := cap(m)
fmt.Println(cap)
}
报错信息:
./main.go:9:12: invalid argument m (type map[int]string) for cap
正确:
package main
import (
"fmt"
)
func main() {
m := map[int]string{1: "a", 2: "b", 3: "c"}
len := len(m)
fmt.Println(len)
}
三、使用总结
func main() {
m := map[string]string{
"key1": "value1",
"name": "tcy",
"age": "22",
}
m2 := make(map[string]int) // m2 == empty map map[]
var m3 map[string]int // m3 == nil map[]
fmt.Println(m, m2, m3)
//遍历
for k, v := range m {
fmt.Println(k, v) //key1 value1 name tcy age 22
}
//根据key值找value
name := m["name"]
fmt.Println(`m["name"] =`, name)//m["name"] = tcy
if age, ok := m["age"]; ok {
fmt.Println(age) //22
}
//删除值,执行delete的时候,只是把key和value的指针设置为nil 。这样真正的数据会被gc回收
delete(m, "name")
name, ok := m["name"]
fmt.Printf("m[%q] after delete: %q, %v\n", "name", name, ok)
//m["name"] after delete: "", false
}