Go 语言 map的使用
一、map 基本介绍:
map 是 key-value 数据结构,又称为字段或者关联数组
。(类似Python中的字典)
基本语法:
var map 变量名 map[keyType]valueType
- 通常key的类型为:int,string,也可以为bool、数字、指针、channel、接口、结构体、数组;
- 通常value的类型为:数字(整数、浮点数)、string、map、struct;
map声明的案例:
var 变量名 map[string]string // 变量名的key 类型为:string value 类型为:string
var 变量名 map[string]map[string]string // 变量名 key 类型为:string value 类型为: map
注意
:声明是不会分配内存的,初始化需要make,分配内存后才能赋值和使用。
举个栗子:
package main
import "fmt"
func main() {
// map 的声明和注意事项
// 注意: 在使用map 前需要make, 给map 分配数据空间
myMap := make(map[string]string, 10) // 10表示分配给map的空间
myMap["num1"] = "亚索"
myMap["num2"] = "提莫"
myMap["num3"] = "男刀"
fmt.Println("myMap:", myMap)
}
// 输出结果:
myMap: map[num1:亚索 num2:提莫 num3:男刀]
- map在使用前一定要make;
- map的key是不能重复的,若重复了,后面的会覆盖之前的;
- map的value 可以是重复的;
- map的key-value是无序;
二、map的使用方式:
-
方式一:
package main import "fmt" func main() { // 第一种使用方式 var myMap map[string]string // 在使用map前,需要先make,make的作用就是给map分配数据空间 myMap = make(map[string]string) myMap["num1"] = "亚索" myMap["num2"] = "提莫" myMap["num3"] = "男刀" fmt.Println("myMap:", myMap) } // 输出结果: myMap: map[num1:亚索 num2:提莫 num3:男刀]
-
方式二:
package main import "fmt" func main() { // 第二种方式 myMap := make(map[string]string) myMap["num1"] = "亚索" myMap["num2"] = "提莫" myMap["num3"] = "男刀" fmt.Println("myMap:", myMap) } // 输出结果: myMap: map[num1:亚索 num2:提莫 num3:男刀]
-
方式三:
package main import "fmt" func main() { // 第三种方式 myMap := map[string]string{ "num1": "亚索", "num2": "提莫", "num3": "男刀", } fmt.Println("myMap:", myMap) } // 输出结果: myMap: map[num1:亚索 num2:提莫 num3:男刀]
举个栗子:
package main
import "fmt"
func main() {
/*
比如要存放 3 个学生信息,每个学生有 name 和 sex 的信息
思路: map[string]map[string]string
*/
// 注意make的使用
studentsMap := make(map[string]map[string]string)
studentsMap["num1"] = make(map[string]string, 3)
studentsMap["num1"]["name"] = "亚索"
studentsMap["num1"]["sex"] = "男"
studentsMap["num1"]["address"] = "峡谷之巅"
studentsMap["num2"] = make(map[string]string, 3)
studentsMap["num2"]["name"] = "提莫"
studentsMap["num2"]["sex"] = "保密"
studentsMap["num2"]["address"] = "峡谷之巅"
fmt.Println("studentsMap:", studentsMap)
}
// 输出结果:
studentsMap: map[num1:map[address:峡谷之巅 name:亚索 sex:男] num2:map[address:峡谷之巅 name:提莫 sex:保密]]
三、map的增、删、改、查:
-
map 增加和更新:
package main import "fmt" func main() { // map 增加 myMap := make(map[string]string) myMap["name"] = "亚索" myMap["sex"] = "男" // map 更改 myMap["name"] = "亚索" myMap["sex"] = "保密" fmt.Println("myMap:", myMap) } // 输出结果: myMap: map[name:亚索 sex:保密]
key 还没有,就相当于增加,若key 已经存在,相当于修改
-
map 删除:
基本语法:delete(map,“key”);delete是一个内置函数
- 若key存在,就删除key-value;
- 若key不存在,不操作,也不会报错;
package main import "fmt" func main() { // map 的增加 myMap := make(map[string]string) myMap["name"] = "亚索" myMap["sex"] = "男" // 删除已经存在的key delete(myMap, "sex") // 删除不存在的key, 删除不会报错、也不会报错 delete(myMap, "address") fmt.Println("myMap:", myMap) } // 输出结果: myMap: map[name:亚索]
-
map 查找:
package main import "fmt" func main() { // map 的查找 myMap := make(map[string]string) myMap["name"] = "亚索" myMap["sex"] = "男" val, got := myMap["name"] if got { fmt.Println("值为:", val) }else { fmt.Println("没有值!") } } // 输出结果: 值为: 亚索
若myMap 这个 map 中存在 key为"name",那么got就会返回true,否则返回false
四、map 遍历:
map遍历仅能使用for-range
package main
import (
"fmt"
)
func main() {
// map for-range 的使用
myMap := make(map[string]map[string]string)
myMap["num1"] = make(map[string]string)
myMap["num1"]["name"] = "亚索"
myMap["num1"]["sex"] = "男"
myMap["num2"] = make(map[string]string)
myMap["num2"]["name"] = "男刀"
myMap["num2"]["sex"] = "男"
for k, v := range myMap{
fmt.Println("k=", k)
for k1, v1 := range v{
fmt.Printf("\t k1=%v v1=%v", k1, v1)
}
fmt.Println()
}
}
// 输出结果:
k= num2
k1=name v1=男刀 k1=sex v1=男
k= num1
k1=name v1=亚索 k1=sex v1=男
五、map 排序:
- go 中
没有
专门方法针对map的可以进行排序; - go 中 map 默认是无序;
- go 中 map 排序,是先将 key 进行排序,然后根据key值遍历输出;
举个栗子:
package main
import (
"fmt"
"sort"
)
func main() {
// 按照 map 的key 顺序进行排序输出
// 1.先将 map 的 key 放入到 切片中
// 2.对切片操作
// 3.遍历切片, 按照key来输出map的值
mySort := make(map[int]int)
mySort[1] = 100
mySort[3] = 66
mySort[2] = 88
mySort[5] = 16
fmt.Println("mySort=", mySort)
var keys []int
for k, _ := range mySort {
keys = append(keys, k)
}
fmt.Println("keys", keys)
// 对切片排序
sort.Ints(keys)
fmt.Println("keys", keys)
for _, v := range keys{
fmt.Printf("mySort[%v]=%v\n", v, mySort[v])
}
}
// 输出结果:
mySort= map[1:100 2:88 3:66 5:16]
keys [3 2 5 1]
排序后=keys [1 2 3 5]
mySort[1]=100
mySort[2]=88
mySort[3]=66
mySort[5]=16
六、map 使用细节:
-
map 是引用类型,遵守引用类型传递机制:
package main import "fmt" func test (map1 map[int]int) { map1[10] = 600 } func main() { // map 是引用类型 myMap := make(map[int]int) myMap[10] = 1000 myMap[1] = 1000 test(myMap) fmt.Println("myMap值:", myMap) } // 输出结果: myMap值: map[1:1000 10:600]
-
map 中的value,数据结构通常为struct类型:
package main import "fmt" // 定义一个学生的结构体 type Stu struct { Name string Age int Address string } func main() { // map 的value, 经常用struct 类型 students := make(map[string]Stu) // 创建2个学生 stu1 := Stu{"Tom", 18, "北京"} stu2 := Stu{"mary", 20, "上海"} students["num1"] = stu1 students["num2"] = stu2 fmt.Println(students) // 遍历得到每个学生信息 for k, v := range students { fmt.Println("学生编号为:", k) fmt.Println("学生的姓名为:", v.Name) fmt.Println("学生的年龄为:", v.Age) fmt.Println("学生的地址为:", v.Address) } fmt.Println() } // 输出结果: map[num1:{Tom 18 北京} num2:{mary 20 上海}] 学生编号为: num1 学生的姓名为: Tom 学生的年龄为: 18 学生的地址为: 北京 学生编号为: num2 学生的姓名为: mary 学生的年龄为: 20 学生的地址为: 上海