Go基础编程——map
2018-01-17 15:51
274 查看
map
1、类 似 其 它 浯 言 中 的 唁 希 表 或 者 字 典 , 以 key-value形式存储数据 :
2、Key必须 是 支 持==或 ! = 比 较 运 算 的 类 型 , 不 可 以 是函数、 map或者slice
3、Map查找 比 线 性 搜 索 快 很 多 , 但 比 使 用 索 引(数组,Slice等) 访 问 数 据 的 类 型 慢 100 倍
4、Map使用make()创建 , 支 持:=这 种 简 写 方 式
5、make([keyType]valueType, cap) , cap 表 示 容 量 , 可 省 略
6、超 出 容 量 时 会 自 动 扩 容 , 但 尽 量 提供 一 个 台 理 的 初 始 值
7、使用len()获 取 元 素 个数
8、键值 对 不 存 在 时 自 动 添 加 , 使 用delete() 删 除 某键值对
9、使 用 for range 对 map 和Slice 进 行 迭 代 操 作
创建一个空的map
其中int是key的类型,string是value的类型。
使用make()来创建map的方式如下:
可以使用这样的方式给map赋值。
使用这样的方式取出值。同时删除一个值可以使用如下程序来完成:
运行结果
这样就实现了删除一个元素。delete(m,1)第一个参数m是指的要删除的元素所在的map类型,1代表要删除的元素的key值。
当然企业级开发都是使用复杂的map来实现功能的,接下来就试试:
运行结果
可以看到第一次初始化只是对最外层进行了初始化,第二次才是到里层。这里有两种方法检查map是否被初始化。
第一种方法就是直接取那个值,如下
这时候fmt.Println(a)得到就是一个空字符串,
这里推荐第二种方法,使用多返回值的特性返回一个bool类型更加好判断是否有值,以便在合适的时候给它初始化。示例程序如下:
运行结果
这样就实现了,首先判断出某个值未被赋值的时候给他在合适的地方初始化。记住一个核心点,多个map嵌套的时候每一级都要进行单独的初始化。
Slice与map结合的使用场景
运行结果
这个就是以map为类型,初始值为3个的Slice。
这种形式初始化的sm是空值,因为循环遍历出来的v只是一个拷贝,在计算机中的地址不是原来的内存地址,所以,给拷贝出来的v赋值不会影响到sm中对应的v值。下边来看看每次的循环拷贝出来的内存地址和原来sm的内存地址不一样,就可以解释了,看如下程序:
运行结果
可以看出每次拷贝都是放在不同内存地址。一般情况我们希望通过循环来给sm初始化赋值,这时候只需要获取返回来的索引就可以解决问题,看如下解决办法:
运行结果
这样以索引的形式赋值,就不会是空的,索引是在内存中是唯一的,这样就就能够对迭代对象进行直接拷贝。
map是无序性的,但是很多时候需要map间接的成为有序的,这时候就需要借助Slice,主要是通过给map的key值进行排序来达到对map的排序,看如下程序:
运行结果
思考
使用for range尝试将类型为map[int]string的键和值进行交换,是它变成map[string]int
如下所示;
运行结果
1、类 似 其 它 浯 言 中 的 唁 希 表 或 者 字 典 , 以 key-value形式存储数据 :
2、Key必须 是 支 持==或 ! = 比 较 运 算 的 类 型 , 不 可 以 是函数、 map或者slice
3、Map查找 比 线 性 搜 索 快 很 多 , 但 比 使 用 索 引(数组,Slice等) 访 问 数 据 的 类 型 慢 100 倍
4、Map使用make()创建 , 支 持:=这 种 简 写 方 式
5、make([keyType]valueType, cap) , cap 表 示 容 量 , 可 省 略
6、超 出 容 量 时 会 自 动 扩 容 , 但 尽 量 提供 一 个 台 理 的 初 始 值
7、使用len()获 取 元 素 个数
8、键值 对 不 存 在 时 自 动 添 加 , 使 用delete() 删 除 某键值对
9、使 用 for range 对 map 和Slice 进 行 迭 代 操 作
创建一个空的map
m:=map[int]string{} fmt.Println(m)
其中int是key的类型,string是value的类型。
使用make()来创建map的方式如下:
n:=make(map[int]string) m[1]="Hello"
可以使用这样的方式给map赋值。
a:=m[1]
使用这样的方式取出值。同时删除一个值可以使用如下程序来完成:
m:=map[int]string{} m[1]="Hello" a:=m[1] fmt.Println(m) delete(m,1) fmt.Println(m) /*n:=make(map[int]string) fmt.Println(n)*/ fmt.Println(a)
运行结果
map[1:Hello] map[] Hello
这样就实现了删除一个元素。delete(m,1)第一个参数m是指的要删除的元素所在的map类型,1代表要删除的元素的key值。
当然企业级开发都是使用复杂的map来实现功能的,接下来就试试:
m:=make(map[int]map[int]string) m[1]=make(map[int]string) fmt.Println(m) m[1][1]="Hello" a:=m[1][1] fmt.Println(m) fmt.Println(a)
运行结果
map[1:map[]] map[1:map[1:Hello]] Hello
可以看到第一次初始化只是对最外层进行了初始化,第二次才是到里层。这里有两种方法检查map是否被初始化。
第一种方法就是直接取那个值,如下
m:=make(map[int]map[int]string) m[1]=make(map[int]string) fmt.Println(m) //m[1][1]="Hello" a:=m[1][1] fmt.Println(m) fmt.Println(a)
这时候fmt.Println(a)得到就是一个空字符串,
这里推荐第二种方法,使用多返回值的特性返回一个bool类型更加好判断是否有值,以便在合适的时候给它初始化。示例程序如下:
m:=make(map[int]map[int]string) m[1]=make(map[int]string) fmt.Println(m) //m[1][1]="Hello" a,ok:=m[1][1] if !ok{ m[1][1]="Hello" } a=m[1][1] fmt.Println(m) fmt.Println(a)
运行结果
map[1:map[]] map[1:map[1:Hello]] Hello
这样就实现了,首先判断出某个值未被赋值的时候给他在合适的地方初始化。记住一个核心点,多个map嵌套的时候每一级都要进行单独的初始化。
Slice与map结合的使用场景
sm:=make([]map[int]string,3) for _,v:=range sm{ v=make(map[int]string,1) v[1]="China" fmt.Println(v) } fmt.Println(sm)
运行结果
map[1:China] map[1:China] map[1:China] [map[] map[] map[]
这个就是以map为类型,初始值为3个的Slice。
这种形式初始化的sm是空值,因为循环遍历出来的v只是一个拷贝,在计算机中的地址不是原来的内存地址,所以,给拷贝出来的v赋值不会影响到sm中对应的v值。下边来看看每次的循环拷贝出来的内存地址和原来sm的内存地址不一样,就可以解释了,看如下程序:
sm:=make([]map[int]string,3) for _,v:=range sm{ v=make(map[int]string,1) v[1]="China" fmt.Println(v) fmt.Printf("%p\n",v) } fmt.Println(sm) fmt.Printf("%p\n",sm)
运行结果
map[1:China] 0xc042068060 map[1:China] 0xc042068090 map[1:China] 0xc0420680c0 [map[] map[] map[]] 0xc0420023e0
可以看出每次拷贝都是放在不同内存地址。一般情况我们希望通过循环来给sm初始化赋值,这时候只需要获取返回来的索引就可以解决问题,看如下解决办法:
sm:=make([]map[int]string,3) for i,_:=range sm{ sm[i]=make(map[int]string,1) sm[i][1]="China" fmt.Println(sm[i]) fmt.Printf("%p\n",sm[i]) } fmt.Println(sm) fmt.Printf("%p\n",sm)
运行结果
map[1:China] 0xc04207a060 map[1:China] 0xc04207a090 map[1:China] 0xc04207a0c0 [map[1:China] map[1:China] map[1:China]] 0xc0420443a0
这样以索引的形式赋值,就不会是空的,索引是在内存中是唯一的,这样就就能够对迭代对象进行直接拷贝。
map是无序性的,但是很多时候需要map间接的成为有序的,这时候就需要借助Slice,主要是通过给map的key值进行排序来达到对map的排序,看如下程序:
m:=map[int]string{1:"a",2:"b",3:"c",4:"d",5:"e"} s:=make([]int,len(m)) i:=0 for k,_:=range m { s[i]=k i++ } sort.Ints(s) fmt.Println(s) for i=1;i<=len(s);i++{ for k,_:=range m{ if k==i{ a:=m[k] fmt.Print(a) } } }
运行结果
[1 2 3 4 5] abcde
思考
使用for range尝试将类型为map[int]string的键和值进行交换,是它变成map[string]int
如下所示;
m1:=map[int]string{1:"a",2:"b",3:"c"} m2:=make(map[string]int) for k,v:=range m1{ m2[v]=k } fmt.Print(m1,m2)
运行结果
map[1:a 2:b 3:c] map[a:1 b:2 c:3]
相关文章推荐
- Go基础编程:复合类型—map
- [GO编程] GO入门语法基础
- Go 并发编程基础(一)goroutine,channel
- Go编程基础—defer、return、返回值之间执行顺序的坑
- Go基础编程:环境搭建
- Go基础编程:复合类型—数组
- Go语言面组合式向对象编程基础总结
- Go语言学习三:Go基础(iota,array,slice,map,make,new)
- Go语言基础学习九-过程式编程一
- Go语言基础入门--数组,切片,map
- Go编程基础—go常用命令
- [译] Go 并发编程基础
- Go基础编程:HTTP报文浅析
- GO_05:GO语言基础map与函数
- Go编程基础之三 类型与变量
- Go编程基础—基本介绍
- Go基础编程:作用域
- Go编程基础——数组array
- Go编程基础—数组(array)
- Go基础编程:第一个Go程序