[Go]新手入门:map的介绍与使用
Posted 凌星An
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了[Go]新手入门:map的介绍与使用相关的知识,希望对你有一定的参考价值。
介绍
Go语言中的map是一种存放元素对的无序集合(数据结构)
元素对:即key-value对;key为键值,value为值;key可以理解为数组的下标,根据key可以快速的找到对应的value值
map在其他语言中也存在对应的数据结构 eg:Python中字典(dict);C++中的map;Java中的HashMap
Go中的map与其他语言存在区别:map作为语言内置类型存在。
使用
创建变量
map是一种引用类型,可以使用make函数或者初始化语句来创建。
eg:
//声明一个map变量map0 ;key为int类型,value为string类型
var map0 map[int]string
//未初始化的map默认值为nil
//使用len函数可以得出map变量中元素个数,
//如果是传入未初始的map结果为0
fmt.Println(map0 == nil, "map0 len", len(map0))
//true map0 len 0
//使用make函数创建map变量
map1 := make(map[int]string)
//往map1中添加元素对
map1[1] = "one"
map1[2] = "two"
//验证结果
fmt.Println(map1[1], map1[2])
fmt.Println("map1 len:", len(map1))
//one two
//map1 len: 2
//使用make函数创建map变量,此处指明了初始容量大小为10
//map可以根据新增的元素对,进行伸缩处理
//可以不指明初始容量,让其自动扩展
//但是最有效率的方法是,指明一个大概的范围,
//防止其扩容(内存分配,重新哈希)造成的效率损失
map3 := make(map[int]string, 10)
fmt.Println("map3 len:", len(map3))
//0 未存入元素
//使用初始化语句创建map变量map2
map2 := map[int]string1: "one", 2: "two"
fmt.Println(map2[1], map2[2])
基本操作
增加元素对
往map变量里面增加元素对的方法在上面已经展示过了
mapVar[key]=value
mapVar : map变量
key :新增元素对的键值
value :新增元素对的值
map1 := make(map[int]string)
map1[1] = "one"
map1[2] = "two"
fmt.Println(map1[1], map1[2])
查找元素对
我们可以使用if语句来判断map变量中是否存在对应的元素对
eg:
map1 := make(map[int]string)
map1[1] = "one"
map1[2] = "two"
//ok是一个bool变量
//为true时,表示map中存在对应元素对,v变量中存储value值
//为false时,表示map变量中不存在对应元素对
if v, ok := map1[2]; ok
fmt.Println(v)
else
fmt.Println("map1中不存在键值:2")
if v, ok := map1[3]; ok
fmt.Println(v)
else
fmt.Println("map1中不存在键值:3")
//two
//map1中不存在键值:3
遍历
使用for循环搭配range关键字可以遍历map
eg:
map1 := make(map[int]string)
map1[1] = "one"
map1[2] = "two"
// k变量存储键值
// v变量存储键值对应的值
for k, v := range map1
fmt.Println("key:", k, "value:", v)
//key: 1 value: one
//key: 2 value: two
// k变量存储键值
for k := range map1
fmt.Println("key:", k)
//key: 1
//key: 2
//使用匿名变量的形式,只接收值,不需要返回键值
for _, v := range map1
fmt.Println("value:", v)
//value: one
//value: two
注:
map是一种无序的数据结构,也就是说遍历的顺序时未知的,可能每次都不一样;如果希望的到有序的结果;可以使用sort包中对应的函数进行排序
删除元素对
Go中提供内置函数delete可以删除map变量中的单个元素对
usage:
delete(mapVar,key)
mapVar: map变量 key:键值
eg:
map1 := make(map[int]string)
map1[1] = "one"
map1[2] = "two"
for k, v := range map1
fmt.Println("key:", k, "value:", v)
//删除键值为1的元素对
delete(map1, 1)
for k, v := range map1
fmt.Println("key:", k, "value:", v)
//删除不存在的元素对
delete(map1, 3)
for k, v := range map1
fmt.Println("key:", k, "value:", v)
/*
key: 1 value: one
key: 2 value: two
key: 2 value: two
key: 2 value: two
*/
注:
内置函数delete:
func delete(m map[Type]Type1, key Type)
如果 m 为 nil 或没有这样的元素,则 delete 是空操作。
修改元素对
mapVar[key]= NewValue
mapVar :map变量
key:键值
NewValue :新的值
倘若想修改key值,可以先使用delete函数删除元素对,在使用mapVar[key]=value的形式添加元素对
eg:
map1 := make(map[int]string)
map1[1] = "one"
map1[2] = "two"
for k, v := range map1
fmt.Println("key:", k, "value:", v)
map1[1] = "first"
for k, v := range map1
fmt.Println("key:", k, "value:", v)
/*
key: 1 value: one
key: 2 value: two
key: 1 value: first
key: 2 value: two
*/
使用注意事项
在遍历时修改map的值
这种是被允许的;也是安全的不会出现错误
map1 := make(map[string]int)
map1["one"] = 1
map1["two"] = 2
for k, v := range map1
map1[k] = v + 1
fmt.Println("key:", k, "value:", map1[k])
key: one value: 2
key: two value: 3
在遍历时新增或者删除 元素对
这种操作也是ok的,是安全的,不会出现任何错误
eg:
map1 := make(map[int]int)
for i := 0; i < 10; i++
map1[i] = i + 10;
for k, v := range map1
if k == 7
map1[77] = 77
delete(map1, k)
fmt.Println("delete <k,v>:<", k, v, ">", " map1:", map1)
delete <k,v>:< 3 13 > map1: map[0:10 1:11 2:12 4:14 5:15 6:16 7:17 8:18 9:19]
delete <k,v>:< 4 14 > map1: map[0:10 1:11 2:12 5:15 6:16 7:17 8:18 9:19]
delete <k,v>:< 6 16 > map1: map[0:10 1:11 2:12 5:15 7:17 8:18 9:19]
delete <k,v>:< 7 17 > map1: map[0:10 1:11 2:12 5:15 8:18 9:19 77:77]
delete <k,v>:< 9 19 > map1: map[0:10 1:11 2:12 5:15 8:18 77:77]
delete <k,v>:< 1 11 > map1: map[0:10 2:12 5:15 8:18 77:77]
delete <k,v>:< 2 12 > map1: map[0:10 5:15 8:18 77:77]
delete <k,v>:< 5 15 > map1: map[0:10 8:18 77:77]
delete <k,v>:< 8 18 > map1: map[0:10 77:77]
delete <k,v>:< 77 77 > map1: map[0:10]
delete <k,v>:< 0 10 > map1: map[]
并发环境
在并发环境下对map进行读写操作是不安全的,存在数据竞争。
在Go 1.9后,引入sync.Map 在并发下是安全的
const size = 100
map1 := make(map[int]int)
go func()
for i := 0; i < size; i++
map1[i] = i
()
go func()
for i := 0; i < size; i++
fmt.Println(map1[i])
()
go run -race main.go
==================
WARNING: DATA RACE
关于nil map
仅仅声明map变量,它的默认值是nil。
对于值为nil的map变量,go圣经中有一句说明:
Most operations on maps, including lookup, delete, len, and range loops, are safe to perform on a nil map reference, since it behaves like an emtpy map. But storing to a nil map cause a panic.
如果往nil map存储值得时候将会导致程序崩溃
var m map[int]int
m[1] = 1
//panic: assignment to entry in nil map
觉得不错,来个赞呗
以上是关于[Go]新手入门:map的介绍与使用的主要内容,如果未能解决你的问题,请参考以下文章
Go入门教程2内置基础类型(Boolean数值字符串错误类型),分组,iota枚举,array(数值),slice(切片),map(字典),make/new操作,零值
Golang 入门总结:Go Module, for range, 切片, map, struct 等使用和实现
Golang 入门总结:Go Module, for range, 切片, map, struct 等使用和实现