Go语言中的map(映射、字典)是一种内置的数据结构,它是一个无序的键值对(key:value)集合,key类似于索引,可以通过key快速检索value。
2.1字典的声明
var m1 map[keyType]valueType
a.一个map里所有的键都是唯一的。
b.所有的键必须支持“==”和“!=”操作符的类型,切片、函数以及包含切片的结构体,因为具有引用语义,不能作为键,使用这些类型会造成编译错误。
c.map值可以是任意类型,没有 限制。
d.map里所有键的数据类型必须是相同的,值的数据类型也必须相同,但键和值的数据类型可以不相同。
e.因为map使用的hash表来实现的,所以map是无序的,无法决定他们的返回顺序。所以每次打印结果顺序有可能不同。
2.2空字典
仅仅声明、而没有初始化的字典为空字典。空字典是不能存储键值对的。
package main
import "fmt"
func main() {
var m1 map[int]string
fmt.Println(m1) //仅声明的字典是空字典,打印结果m1=map[]
fmt.Println(m1 == nil)
m1[1] = "a"
fmt.Println(m1) //空字典是不能存储键值对的,程序出现panic错误
}
程序运行结果:
map[]
true
panic: assignment to entry in nil map
goroutine 1 [running]:
main.main()
2.3字典初始化
方式 | 示例 |
先声明,再初始化 | var m1 map[int]string m1 = map[int]string{}//打印结果为map[],非空字典 |
var m2 map[int]string m2 = map[int]string{1: "mike", 2: "yoyo"} |
|
声明的同时初始化 | var m3 map[int]string = map[int]string{1: "mike", 2: "yoyo"} |
自动推导类型初始化 | var m4 = map[int]string{1: "mike", 2: "yoyo"} |
m5 := map[int]string{1: "mike", 2: "yoyo"} | |
通过make()函数创建 | m6 := make(map[int]string, 10) //打印结果为map[],非空字典 |
map超出容量时会自动扩容。
3.1赋值
a.对已存在的键值赋值:相当于对已知键值对进行修改。
b.添加不存在的键值对:前提是字典完成过初始化
mapName[key] = value
package main
import "fmt"
func main() {
m := map[int]string{1: "mike", 2: "yoyo"}
/*对已经存在的键值赋值*/
m[1] = "Wei Xiaobao"
fmt.Println("m =", m)
/*添加不存在的键值对*/
m[3] = "Zhang Sanfeng"
fmt.Println("m =", m)
}
运行结果:
3.2 遍历
方式1:
for k,v :=range mapName{
fmt.Printf("%v:%v\n",k,v) //%v:以默认模式输出,输出格式:“key: value”
}
方式2:
for k :=range mapName{
fmt.Printf("%v:%v\n", k, mapName[k]) //mapName[k]:通过键k得到对应的value
}
方式3:
for _,v := range mapName{
fmt.Printf("v = %v\n",v) //不能通过v得到key值,只能通过键获取值,不能通过值获取键
}
package main
import "fmt"
func main() {
m := map[int]string{1: "mike", 2: "yoyo"}
fmt.Println("方式1:")
for k, v := range m { //返回key和value
fmt.Printf("\t%v:%v\n", k, v) //%t :表示一个tab键
}
fmt.Println("方式2:")
for k := range m { //仅返回key
fmt.Printf("\t%v:%v\n", k, m[k]) //mapName[k]: 通过k再去得到对应的value
}
fmt.Println("方式3:")
for _, v := range m { //仅返回value,_站位,表示忽略这个位置的返回值
fmt.Printf("\tv=%v\n", v)
}
}
3.3查询
方式1:
value, ok := mapName[key] //ok的结果有两种:true或false
if ok{ //如果ok为true,执行括号内代码
/*处理找到的值*/
}
方式2:
//ok为true或或false,如果ok为true,执行括号内代码
if value, ok := mapName[key];ok{
/*处理找到的value*/
}
package main
import "fmt"
func main() {
m := map[int]string{1: "mike", 2: "yoyo"}
value1, ok := m[1] //ok 两种结果:true或false
if ok {
//如果ok为true,执行代码
fmt.Printf("找到了:key = 1, value = %v\n", value1)
}
value2, ok := m[3]
if ok {
//如果ok为true,执行代码
fmt.Printf("找到了:key = 3, value = %v\n", value2)
} else {
//如果ok为false,执行代码
fmt.Printf("没有找到!\n")
}
}
3.4删除键值对
delete(mapName, key)
a.key只能是一个,不能是多个,即每次只能删除一个元素
b.如果这个key不存在,则这个函数将什么都不发生。
package main
import "fmt"
func main() {
m := map[int]string{1: "mike", 2: "yoyo", 3: "Zhang Sanfeng"}
fmt.Println(m)
delete(m, 1) //删除key为1的键值对
fmt.Println(m)
delete(m, 4) //4不是字典的键,删除key为4的键值对,没有任何改变
fmt.Println(m)
}
字典变量作为函数参数,再函数间传递的是引用传递,不是值传递。
package main
import "fmt"
func main() {
m := map[int]string{1: "mike", 2: "yoyo", 3: "lily"}
fmt.Println("主函数(删除前): ")
fmt.Println("\tm =", m)
deleteMap(m, 2) //调用函数
fmt.Println("主函数(删除后): ")
fmt.Printf("\tm=%v, len(m)=%d\n", m, len(m))
for k, v := range m {
fmt.Printf("\tk = %d ----> v = %s\n", k, v)
}
}
func deleteMap(m map[int]string, key int) {
delete(m, key) //删除key为2的键值对
fmt.Println("自定义函数:")
fmt.Printf("\tm = %v, len(m)=%d\n", m, len(m))
for k, v := range m {
fmt.Printf("\tk = %d ----> v = %s\n", k, v)
}
}