Go Map
#### Go map
***如果生命是一道墙,那么声声必有回响***
上一节我们学习了数组与切片,学习的还是基础部分, 高级部分有二维数组,多维数组...;
在这里先不写高级部分,高级部分与初级部分并没有太大区别,一个是多维切片,在每一维使用前都需要make,第二个是遍历时需要多层循环;
##### map
在 Go 中map 是key:value 数据结构,类似python 中的字典;
基本语法:
var 变量名 map[keyType]valueType
其中key 可以是如下类型:
bool, 数字,string, 指针, channel,同样还可以是包含前几个类型的接口,结构体,数组;
不过一般开发使用中key 通常为int,string;
key 需要满足可以使用== 判断,所以slice,map,函数这三个类型不可以作为map 的key ;
value 的数据类型同key 一样, 通常为数字,string, map,struct;
案例:
var a map[string]string var b map[int]string var c map[string]map[int]string var d map[string]int
map 是引用类型和slice 同样,声明或定义是不会分配内存,初始化都需要make 才能使用;
package main
import "fmt"
func main(){
var a map[string]string
a = make(map[string]string)
a["01"] = "01"
a["02"] = "02"
a["03"] = "03"
a["01"] = "04"
fmt.Println(a)
}
1. map 在使用前需要make ;
2. map 的key 不能重复,如果重复则key 的值为最后一次赋的值 ;
3. map 是无序的,所以如果需要对map 排序,则需要对key 进行排序 ;
---
##### map 的声明和初始化方式
package main
import "fmt"
func main(){
// 1. 先声明,再make ,最后使用
var a map[string]string
a = make(map[string]string)
a["01"] = "01"
fmt.Println(a)
// 2. 直接使用类型推导
b := make(map[string]string)
b["01"] = "01"
fmt.Println(b)
// 3. 字面量方式
var c = map[string]string{
"01":"01",
}
fmt.Println(c)
}
##### map 的增删改查
map 的增加和更改
map[key] = value // 如果map 内不存在key 则属于添加操作,否则属于更改操作;
package main
import "fmt"
func main(){
// 1. 先声明,再make ,最后使用
var a map[string]string
a = make(map[string]string)
// 增加操作
a["01"] = "01"
a["02"] = "02"
// 更改操作
a["01"] = "10"
fmt.Println(a) // map[01:10 02:02]
}
map 删除
delete(map,key) ,delete 是内置函数,如果key 存在则会删除这对key:value,如果key 不存在,则不会操作,也不会报错;
package main
import "fmt"
func main(){
// 1. 先声明,再make ,最后使用
var a map[string]string
a = make(map[string]string)
// 增加操作
a["01"] = "01"
a["02"] = "02"
// 更改操作
a["01"] = "10"
fmt.Println(a) // map[01:10 02:02]
// 删除已经存在的key
delete(a,"02")
// 删除不存在的key
delete(a,"10")
}
---
注意: 在Go 中没有专门的函数可以一次性删除map 中所以的key, 也就是说没有办法一次性清空map,
如果需要删除所有的key, 则需要遍历map , 一个一个删除; 另一个办法则是让gc 回收: map = make(map[keyType][valueType]);
map 查找
val,res = map[key]
如果map 中存在key 则返回value,同时返回res=true,否则不会返回value,res=false;
package main
import "fmt"
func main(){
// 1. 先声明,再make ,最后使用
var a map[string]string
a = make(map[string]string)
// 增加操作
a["01"] = "01"
a["02"] = "02"
var value string
var res bool
value,res = a["01"]
if res {
// 如果有这个key
fmt.Println("key:01 value:",value)
} else {
// 如果没有这个key
fmt.Println("no value",value)
}
value,res = a["10"]
if res {
// 如果有这个key
fmt.Println("key:10 value:",value)
} else {
// 如果没有这个key
fmt.Println("no value",value)
}
}
##### map 的遍历
map 的遍历方式可以使用for-range 方式
package main
import "fmt"
func main() {
// 1. 普通的map
var a map[string]string
a = make(map[string]string)
// 增加操作
a["01"] = "01"
a["02"] = "02"
for key,value := range a {
fmt.Println(key+"=",value)
}
// map 的value 还是一个map
var b map[string]map[string]string
b = make(map[string]map[string]string)
b["01"] = map[string]string{"001":"0001"} // 第二层这里使用的是字面量方式
// 也可以使用这样的方式
c := make(map[string]string)
c["002"] = "0002"
b["02"] = c
fmt.Println(b)
// 复杂map 的遍历
for key,value := range b {
for key2,value2 := range value {
fmt.Printf("first key=%s,first value=%v | second key=%s,second value=%s\n",key,value,key2,value2)
}
}
}
##### map 的长度使用len 函数
##### map 类型的切片
如果切片的数据类型是map , 那么map 的个数就可以动态变化了,这个在json 中比较常用,json 序列化和反序列化后面会学习到;
package main
import "fmt"
func main() {
// 声明切片的类型为map
var arr []map[string]string
// 声明一个map 类型
var a map[string]string
// 初始化map
a = make(map[string]string)
// map 赋值
a["01"] = "01"
// 初始化切片
arr = make([]map[string]string,0) // append 函数底层会检查是否make ,所以这一行可以省略;
arr = append(arr,a)
// 再添加一个map
var b map[string]string
b = make(map[string]string)
b["001"] = "001"
arr = append(arr,b)
fmt.Println(arr)
}
##### map 排序
在上面我们知道了,map 本身是无序的,所以排序需要先对key 排序,然后按排序后的key 输出map即可;
package main
import (
"fmt"
"sort"
)
func main() {
var a map[string]string
a = make(map[string]string)
a["01"] = "01"
a["first"] = "first"
a["second"] = "second"
a["third"] = "third"
a["fourth"] = "fourth"
// 输出是无序的,多运行几次即可看到
for k,v := range a {
fmt.Println(k,v)
}
// 对map 排序,需要先对key 排序
var keySlice []string
for key,_ := range a {
keySlice = append(keySlice,key)
}
// 排序
// 排序前
fmt.Println(keySlice)
sort.Strings(keySlice)
// 排序后
fmt.Println(keySlice)
// 按排序后的key 输出map
for _,key := range keySlice {
fmt.Println(key,a[key])
}
}
map 的使用注意事项
1. map 是引用类型,遵守引用类型传递机制,在函数内部修改后,会改变原来的值 ;
2. map 会自动扩容,可以动态增长;
package main
import "fmt"
func test01(a map[string]string){
// 新增加一个key:value
a["02"] = "02"
}
func main() {
var a map[string]string
a = make(map[string]string)
a["01"] = "01"
a["first"] = "first"
// 传入函数前
fmt.Println(a) //map[01:01 first:first]
// 传入函数后
// 可以看出map 是引用类型,遵守引用传递机制
test01(a)
fmt.Println(a) //map[01:01 first:first 02:02]
}
最新文章会在微信公众号,欢迎关注学习交流

每天进步一点点!加油

浙公网安备 33010602011771号