在刚刚接触go语言的时候,就看到很多地方出现了map
。就对这个map
很困惑,那么这个map
究竟是什么呢。让我们一起来看一看吧。
map (映射)是一个种数据结构,用于存储一些无序的键值对。映射使用了两个数据结构来存储数据。第一个数据结构是数组,内部存储的是用户选择桶的散列值。第二个数据结构是一个字节数组,用于存储键值对。映射是一个存储键值对的无序集合。
创建和初始化
go语言中可以使用make函数,也可以使用使用字面量的方法来创建映射(map)。如下所示
//通过make函数 创建一个映射,键类型是string ,值是int
list := make(map[string]int)
list["test"]= 1
fmt.Println(list["test"])
//创建一个映射,键值都是string 使用字面量
data := map[string]string{"top":"is top","bottom":"is bottom"}
fmt.Println(data["top"])
创建映射更常用的方法应该是使用字面量,映射的初始长度会根据初始化时指定的键值对数量来确定,映射的键可以是任何值,这个值可以是内置类型,也可以是结构类型,只要这个值可以用==运算符比较。需要注意是:切片,函数以及包含切片的结构不能做为映射的键。
映射的使用
赋值
//通过make函数 创建一个映射,键类型是string ,值是int
list := make(map[string]int)
//将test的值加入映射
list["test"]= 1
可以通过什么一个未初始化的映射来创建一个nil
映射,nil
映射不能用于储存键值对
var numbers map[int]int
numbers[1]=1 //这里会产生一个错误
判断键是否存在于映射以及取值
判断某个键是否存在于映射中是一个经常使用的操作。从映射中取值时有两个方式。第一个是,同时获取值,以及一个表示键是否存在的标志
data := map[string]string{"top":"is top","bottom":"is bottom"}
val,exists := data["top"]
//如果这个键存在
if exists {
fmt.Println(val)
} else {
fmt.Println("top 不存在")
}
第二个方式是,只获取键对应的值,通过这个值是否是零值来判断是否存在。但是如果这个键对应的刚好是零值,那么这个判断就会不准确
data := map[string]string{"top":"is top","bottom":""}
v := data["bottom"]
if v!="" {
fmt.Println(v)
}else {
fmt.Println("bottom 不存在")
}
v2 := data["left"]
if v2!="" {
fmt.Println(v2)
}else {
fmt.Println("left 不存在")
}
以上代码会得到
bottom 不存在
left 不存在
但实际上映射中是存在键bottom
的
映射的迭代和数组、切片的迭代一样,使用range关键字
data := map[string]string{"top":"is top","bottom":"is bottom","left":"is left","right":"is right"}
for k,v := range data{
fmt.Printf("k:%s v:%s\n",k,v)
}
需要注意的是,因为映射是一个无序集合。所以每次迭代得到的键值对顺序是不一样的。
删除映射中的某一个项,使用内置函数
delete
data := map[string]string{"top":"is top","bottom":"is bottom","left":"is left","right":"is right"}
delete(data,"top")
映射的传递(引用类型)
在函数间传递映射并不会制造出该映射的一个副本。实际上,当传递映射给一个函数,并对
这个映射做了修改时,所有对这个映射的引用都会察觉到这个修改。
func main() {
m := map[int]int{
0:0,
1:1,
2:2,
3:3,
}
fmt.Println(m)
changeMap(m)
fmt.Println(m)
delMap(m)
fmt.Println(m)
}
func changeMap(m map[int]int) {
m[1]=111
}
func delMap(m map[int]int) {
delete(m,1)
}
上面示例将会输出
map[0:0 1:1 2:2 3:3]
map[0:0 1:111 2:2 3:3]
map[0:0 2:2 3:3]
可以看到在changeMap
中改变了map
的值或者delMap
中删除了某一直键值对,main
中的值也改变了。这个特性和切片类似,保证可以用很小的成本来复制映射。