map 是 Go 语言提供的一种抽象数据类型,它表示一组无序的键值对。在后面的讲解中,我们会直接使用 key 和 value 分别代表 map 的键和值。而且,map 集合中每个 key 都是唯一的。
map对value的类型没有限制,但是对key的类型有严格要求:key的类型应该严格定义了作为“==”和“!=”两个操作符的操作数时的行为,因此函数、map、切片不能作为map的key类型。
和切片一样,map也是引用类型,将map类型变量作为函数参数传入不会有很大的性能损耗,并且在函数内部对map变量的修改在函数外部也是可见的。
初始化
字面量
var m1 map[string]string //此时m1不能直接赋值
m := map[int]string{} //虽然此时 map 类型变量 m 中没有任何键值对,但变量 m 也不等同于初值为 nil 的 map 变量。这个时候,我们对 m 进行键值对的插入操作,不会引发运行时异常
内置的make函数
ages := make(map[string]int) // mapping from strings to ints
读写操作
查找和数据读取
map中的元素通过key对应的下标语法访问
m := make(map[string]int)
v := m["key1"]
当我们尝试去获取一个键对应的值的时候,如果这个键在 map 中并不存在,我们也会得到一个值,这个值是 value 元素类型的零值。
m := map[string]int
m["key1"] = 1
m["key2"] = 2
v := m["key1"]
fmt.Println(v) // 1
v = m["key3"]
fmt.Println(v) // 0
Go语言的一个最佳实践是总是使用“comma ok”惯用法读取map中的值。
m := make(map[string]int)
v, ok := m["key1"]
if !ok {
// "key1"不在map中
}
// 只有当ok = true时,所获得的value值才是我们所需要的
写入
map的赋值语法相对简单,例如map[key]=value代表将value与map1哈希表中的key绑定在一起。如果key已经存在于map中,则该插入操作会用新值覆盖旧值。
m := map[string]int {"key1" : 1, "key2" : 2,}
m["key1"] = 11 // 11会覆盖掉旧值1
m["key3"] = 3 // map[key1:11 key2:2 key3:3]
删除
使用内置的delete函数可以删除元素,传给 delete 的键在 map 中并不存在,delete 函数的执行也不会失败,更不会抛出运行时的异常。
m := map[string]int {
"key1" : 1,
"key2" : 2,
}
fmt.Println(m) // map[key1:1 key2:2]
delete(m, "key2") // 删除"key2"
fmt.Println(m) // map[key1:1]
遍历
我们可以像对待切片那样通过for range语句对map中的数据进行遍历
m := map[int]int{
1: 11,
2: 12,
3: 13,
}
for k, v := range m {
fmt.Printf("[%d, %d] ", k, v)
}
参考资料
- 《Go语言圣经》
- 《Go 语言设计与实现》
- 《Go语言第一课》
- 《Go语言底层原理剖析》