目录
map确实不能用==全等操作符来比较, 但是可以通过循环来比较
map是golang中复杂数据的一种, 由key和value组成, 在golang中一个map就是对一个哈希表的引用, map定义时遵守map[T]V规则, 指定key和value的类型, key的类型必须支持==运算符来进行比较, value的类型则没有限制
创建map
1. 字面量
一般情况下使用字面量创建map会很便捷, 因为字面量的方式既可以创建map也可以初始化map数据.
package main
import (
"fmt"
)
func main() {
map1 := map[string]int{}
map1["zs"] = 19
map1["ls"] = 20
fmt.Println("map1", map1)
map2 := map[string]int{
"zs": 19,
"ls": 20,
}
fmt.Println("map2", map2)
}
2. make 函数
make函数可以创建很多类型的数据(切片, 管道等等), map也不除外, 遵循语法make(map[T]V)的规则, 返回map的引用
package main
import (
"fmt"
)
func main() {
map3 := make(map[string]int)
map3["zs"] = 39
map3["ls"] = 20
fmt.Println("map3", map3)
}
注意 : 只声明map并不能给map增加key-value, 其实也好理解, 声明变量未赋值相当于是该类型的零值, 此map还未分配内存, 因此需要make一下才行
var ma map[string]string
ma = make(map[string]string) // 没有这一行会报错
ma["2"] = "2"
fmt.Println(ma)
map的基本使用
我们可以对map进行增删改查的操作, 删除时需要用到内置函数delete, 查询时只需要访问下map中对应的key即可他会返回对应的value, 以及是否存在, 例 value, isexist := map[key], 如果map中key有对应的value, 则返回对应的value, isexist为true, 反之value为类型的零值, isexist为false
package main
import (
"fmt"
)
func main() {
map2 := map[string]int{
"zs": 19,
"ls": 20,
}
map2["ww"] = 66 // 增加
map2["zs"] = 99 // 修改
delete(map2, "ls") // 删除
value, ok := map2["ww"] // 查询
v, o := map2["a"] // 查询
fmt.Println(value, ok)
fmt.Println(v, o)
fmt.Println("map2", map2)
}
遍历map
map可以用来遍历, 但是最终的顺序是不确定的, 如果想有序的遍历map, 你需要创建一个有序的key数组
无序
letter := map[string]int{
"a": 1,
"b": 2,
"c": 3,
"d": 4,
"e": 5,
"f": 6,
}
for item, ok := range letter {
fmt.Println(item, ok)
}
执行几次后, 发现确实是无序的
有序
有序打印map的思路是, 将map中的key进行排序, 使用切片或数组来保存, 遍历切片或数组打印map中对应value即可
letter := map[string]int{
"a": 1,
"b": 2,
"c": 3,
"d": 4,
"e": 5,
"f": 6,
}
var keys = make([]string, 0, len(letter))
for key, _ := range letter {
keys = append(keys, key)
}
sort.Strings(keys)
fmt.Println("key切片",keys)
for _, key := range keys {
fmt.Println(key, letter[key])
}
map零值
map的零值是nil, map之间不能进行比较, 但是nil除外
var a map[string]int
b := map[string]int{}
fmt.Println(a)
fmt.Println(a == nil)
fmt.Println(b)
fmt.Println(b == nil)
可以看到只有使用var声明变量规定类型的这种方式才算是零值
map确实不能用==全等操作符来比较, 但是可以通过循环来比较
注意使用key作为下标访问map中对应的value是, 如果key不存在则返回零值, 万一比较的时候另一个map中存在value为零值的key时, 那么比较就会出错, 因此在比较的时候必须先判断key是否存在
package main
import (
"fmt"
)
func compare( a, b map[string]int ) bool {
if len(a) != len(b) {
return false
}
for k, v := range a {
if val, ok := b[k]; !ok || val != v {
return false
}
}
return true
}
func main() {
m1 := map[string]int{
"A" : 0,
"C" : 3,
}
m2 := map[string]int{
"C" : 3,
"A" : 0,
}
isSame := compare(m1,m2)
fmt.Println(isSame)
}
总结
- map是复杂数据类型
- map可以进行增删改查的操作
- 遍历map是无序的
- map的零值是nil
- map之间不能进行使用==对比, 但是可以通过循环比较