map
map的介绍
map是key-value数据结构,又称为字段或者关联数组,类似其它语言的集合
map的声明
var 变量名 map[keytype]valuetype
keytype可以是什么类型:
int,float,bool,string,channel,指针,也可以是由这几种类型组成的结构体,数组,接口
通常为int,string
但绝对不能是:slice,map,function
valuetype可以是什么类型:
基本和keytype一致
通常为int,float,string,mao,struct
map声明的例子:
var a map[string]string
var a map[string]int
var a map[int]string
var a map[string]map[string]string
注意:声明并不会分配内存,需要make函数进行初始化分配内存,分配内存后才能赋值和使用
不像数组,声明完就分配好了内存
map的快速入门
func main() {
a := make(map[string]string, 10)
a[“lsh”] = “clw”
a[“clw”] = “zjw”
a[“zjw”] = “lxc”
fmt.Println(a)
}
输出结果:
map[clw:zjw lsh:clw zjw:lxc]
可以看出,map是会自动按照key的大小从小到大来进行排序的
map的key是不能重复的,但是value是可以重复的
map的使用方式
- make
a := make(map[string]string)
a[“lsh”] = “clw”
a[“clw”] = “zjw”
a[“zjw”] = “lxc”
fmt.Println(a) - 直接赋值
b := map[string]string{
“sss”: “1”,
“ss”: “2”,
“ssss”: “3”,
}
fmt.Println(b)
输出结果:
map[ss:2 sss:1 ssss:3]
也是按照key从小到大排序,而且每一个key-value对后都要有“,”,包括最后一个的后面
map的增删查改
- map的增加和更新:
b := map[string]string{
“sss”: “1”,
“ss”: “2”,
“ssss”: “3”,
}
fmt.Println(b)
b[“sss”] = “3”
b[“sssss”] = “2”
fmt.Println(b)
输出结果:map[ss:2 sss:3 ssss:3 sssss:2]
可见b[“sss”] = “3”,若key存在,则修改,若key不存在,则添加
- 删除
- b := map[string]string{
“sss”: “1”,
“ss”: “2”,
“ssss”: “3”,
}
fmt.Println(b)
b[“sss”] = “3”
b[“sssss”] = “2”
fmt.Println(b)
delete(b, “sss”)
delete(b, “sss”)
fmt.Println(b)
输出结果:map[ss:2 ssss:3 sssss:2]
可见,delete删除指定key的对,若没有这个key,也不会报错
- 如果想一次性删除全部,要么遍历map,用delete删除
还可以给这个map直接重新make一个空间,让原来的空间成为垃圾被gc回收
- b := map[string]string{
- 查找
value, find := b[“sssss”]
fmt.Printf(“%v,%v”, value, find)
若b中有sssss,则find返回true,value返回sssss对应的value;否则为false查询map总共有几对key-value对时,用len()函数来求即可
map的遍历
- 不能使用传统的for循环
- 只能使用for-range
func main() {
b := map[string]string{
“sss”: “1”,
“ss”: “2”,
“ssss”: “3”,
}
for k, v := range b {
fmt.Printf(“%v,%v\n”, k, v)
}
}
输出结果:
ssss,3
sss,1
ss,2
此时,k不再是索引,而是键key
map切片
[]数据类型是切片的类型,如果数据类型是map,那么这个切片就是map切片,使map的个数可以动态变化
map和切片都需要make后才能使用
代码:
func main() {
var stu []map[string]string = make([]map[string]string, 2)
stu[0] = make(map[string]string)
stu[0][“name”] = “zjw”
stu[0][“age”] = “19”
stu[1] = make(map[string]string)
stu[1][“name”] = “clw”
stu[1][“age”] = “19”
fmt.Println(stu)
stu2 := make(map[string]string)
stu2[“name”] = “yxn”
stu2[“age”] = “19”
stu = append(stu, stu2)
fmt.Println(stu)
}
输出结果:
[map[age:19 name:zjw] map[age:19 name:clw]]
[map[age:19 name:zjw] map[age:19 name:clw] map[age:19 name:yxn]]
map的使用细节
- map是引用类型,遵守引用类型的传递机制,函数接收map后,内部对map的操作会直接影响到函数外部
func test(a map[string]string) {
a[“s”] = “11”
}
func main() {
b := map[string]string{
“sss”: “1”,
“ss”: “2”,
“ssss”: “3”,
}
fmt.Println(b)
test(b)
fmt.Println(b)
}
输出结果:
map[ss:2 sss:1 ssss:3]
map[s:11 ss:2 sss:1 ssss:3] - map的容量超标后,再想增加元素,会自动扩容,不像切片需要append。
- map的value常常是struct结构体的形式,这很高效,远比map的叠加好
type Stu struct {
name string
age int
}
func main() {
a := make(map[string]Stu, 2)
stu1 := Stu{“aaa”, 1}
stu2 := Stu{“bbb”, 2}
a[“stu1”] = stu1
a[“stu2”] = stu2
fmt.Println(a)
}
输出结果:
map[stu1:{aaa 1} stu2:{bbb 2}]