map是一种键值对的映射,它可以在平时的编程中,存储大部分你需要存储的内容
map的形式
map[数据类型]数据类型
map的创建
[ ]在这里表示可选
make()创建map
变量名 := make(map[数据类型]数据类型, [长度])
创建map顺便赋值
变量名 := map[数据类型]数据类型{[数据值: 数据值, ...]}
什么类型可以作为map的键
以下内容都是赋值操作中的样子,如果是声明的话,那么它的样子如下
var 变量名 map[数据类型]数据类型
如上面的代码所见,它的最后面是不用带 { } 的
string
map[string]数据类型{}
int
map[int]数据类型{}
bool
map[bool]数据类型{}
float
map[float32]数据类型{}
map[float64]数据类型{}
byte
map[byte]数据类型{}
struct
map[结构体名]数据类型{}
interface
map[接口名]数据类型{}
指针
map[指针]数据类型{}
所有类型
interface 表示可以接受上面所列举的类型作为键
如果对空接口 interface{} 有什么不明白的话,可以去看看接口的内容
map[interface{}]数据类型{}
什么类型可以作为map的值
任意类型都可以成为map的值
map的操作
以下操作均以 string 类型为代表
map的初始化
initMap := make(map[string]string, 10)
initMap := map[string]string{
"姓名": "陈九礼",
"年龄": "9999",
}
map的添加
initMap := make(map[string]string, 10)
fmt.Println("没有值时的map:",initMap)
initMap["姓名"] = "陈九礼"
initMap["年龄"] = "9999"
fmt.Println("添加值后的map:", initMap)
输出
没有值时的map: map[]
添加值后的map: map[姓名:陈九礼 年龄:9999]
在添加值的时候要小心点,如果没有给map初始化的话,那么会触发 panic,所以在添加值的时候,最好先判断一下,map是否已经初始化了
var initMap map[string]string
if initMap == nil {
fmt.Println("初始化map操作")
} else {
fmt.Println("没有值时的map:",initMap)
initMap["姓名"] = "陈九礼"
initMap["年龄"] = "9999"
fmt.Println("添加值后的map:", initMap)
}
输出
初始化map操作
如果没有判断,那么 panic 长什么样子?
var initMap map[string]string
initMap["姓名"] = "陈九礼"
initMap["年龄"] = "9999"
输出
panic: assignment to entry in nil map
所以,要多加小心!!!
map的修改
initMap := make(map[string]string, 10)
initMap["姓名"] = "陈九礼"
initMap["年龄"] = "9999"
initMap["性别"] = "男"
fmt.Println("没有修改值前的map:", initMap)
initMap["姓名"] = "陈陈陈"
initMap["爱好"] = "睡觉"
fmt.Println("修改值后的map:", initMap)
输出
没有修改值前的map: map[姓名:陈九礼 年龄:9999 性别:男]
修改值后的map: map[姓名:陈陈陈 年龄:9999 性别:男 爱好:睡觉]
从输出可以看出,姓名已经被改为 “陈陈陈” 了,我们还在上面修改了不存在的值,一般来说,因为修改的值不存在,所以程序会出问题来提醒你,或者不理会这个要修改的值,但是在go的 map 中,如果我们修改了一个不存在的值,那么它会把这个值添加到 map 中
map的删除
initMap := make(map[string]string, 10)
initMap["姓名"] = "陈九礼"
initMap["年龄"] = "9999"
initMap["性别"] = "男"
fmt.Println("没有删除前的map:", initMap)
delete(initMap, "性别")
delete(initMap, "身高")
fmt.Println("删除后的map:", initMap)
输出
没有删除前的map: map[姓名:陈九礼 年龄:9999 性别:男]
删除后的map: map[姓名:陈九礼 年龄:9999]
在上面,我们调用 delete() 方法删除了两个键,一个是 “性别”,一个是 “身高”,性别在调用 delete() 方法后,已经被删除了,而身高这个键本来是不存在的,所以删除无效
就算删除不存在的键,go也不会因此 panic
map的查询
initMap := make(map[string]string, 10)
initMap["姓名"] = "陈九礼"
initMap["年龄"] = "9999"
fmt.Println("姓名", initMap["姓名"])
fmt.Println("年龄", initMap["年龄"])
fmt.Println("身高", initMap["身高"])
输出
姓名 陈九礼
年龄 9999
身高
我们查询一个不存在的时候,如果查询的键不存在,那么会返回该键所对应值的零值
我们修改下值的类型,让我们更清楚的可以看到,查询一个没有的键的时候,它所输出的内容
initMap := make(map[string]bool, 10)
initMap["姓名"] = true
initMap["年龄"] = false
fmt.Println("姓名", initMap["姓名"])
fmt.Println("年龄", initMap["年龄"])
fmt.Println("身高", initMap["身高"])
输出
姓名 true
年龄 false
身高 false
从第三个输出可以看出,它会输出所对应值的类型的零值
如果觉得这样还不清楚,你可以把值换成其它类型去看一看它的输出,加强你的理解
其实在查询的时候,我们是可以判断这个键是否存在的,如下
initMap := make(map[string]bool, 10)
initMap["姓名"] = true
initMap["年龄"] = false
name := initMap["姓名"]
age := initMap["年龄"]
tall, exist := initMap["身高"]
fmt.Println("姓名", name)
fmt.Println("年龄", age)
if exist {
fmt.Println("身高", tall)
}
map 的查询有可以返回一个参数,也有可以返回两个参数的,我们就讲一下返回两个参数的
它返回的第一个参数是键所对应的值(如果这个键不存在的话,返回它所对应值的数据类型的零值)
返回的第二个参数是 bool 类型的值,如果键存在,name返回 true,如果不存在,返回false
这时候我们可以根据它返回的第二个参数,来判断这个键是否存在了
如果map的值是map的情况,我们该如果初始化
var initMap map[string]map[string]string
initMap = make(map[string]map[string]string)
initMap["学生"] = map[string]string{
"姓名": "陈九礼",
"年龄": "9999",
}
fmt.Println(initMap)
输出
map[学生:map[姓名:陈九礼 年龄:9999]]
跟前面其实区别不大,只是我们初始化的时候,要写的长了点
欢迎大家关注下个人的「公众号」:独醉贪欢