map定义
三种方式
package main
import "fmt"
func main() {
// map 的基本定义
// 第一种方式 使用make分配数据空间
var map1 map[string]string
map1 = make(map[string]string, 3)
map1["no1"] = "北京"
map1["no2"] = "天津"
map1["no3"] = "上海"
fmt.Println("map1=", map1)
// 第二种方式
map2 := make(map[string]string)
map2["no1"] = "宋江"
map2["no2"] = "卢俊义"
map2["no3"] = "吴用"
fmt.Println("map2=", map2)
// 第三中方式,使用类型推导
map3 := map[string]string{
"no1": "刘备",
"no2": "关羽",
"no3": "张飞",
}
fmt.Println("map3=", map3)
// 套娃方式
map4 := map[string]map[string]string{
"no1": {"name": "张三", "gender": "男", "address": "北京"},
"no2": {"name": "李四", "gender": "女", "address": "天津"},
"no3": {"name": "王五", "gender": "男", "address": "上海"},
}
}
map删除
删除单个key
delete(map, "key"),delete是内置函数。如果key存在,就删除key-value,如果key不存在,也不会报错。
delete(map1, "no2")
删除全部key
Golang没有提供一次性全部删除的函数,只能遍历全部删除
for i, _ := range map1 {
delete(map1, i)
}
make一个新的空间
map1 = make(map[string]string)
判断某个key是否存在
val, exists := map1["no4"] // exists返回布尔值,存在为true,不存在为false
if exists {
fmt.Println("exists")
} else {
fmt.Println("nonexistence")
}
fmt.Printf("val=%v,exists=%v\n", val, exists)
map遍历
使用 for range遍历即可,多层map,for range多次即可
map 长度
使用len函数
map 切片的使用
package main
import "fmt"
func main() {
// map 切片的使用
map1 := make([]map[string]string, 2)
if map1[0] == nil {
map1[0] = make(map[string]string, 2)
map1[0]["name"] = "宋江"
map1[0]["age"] = "45"
}
if map1[1] == nil {
map1[1] = make(map[string]string, 2)
map1[1]["name"] = "卢俊义"
map1[1]["age"] = "40"
}
// 由于切片只分配了2个空间,再追加map的话需使用append函数
mapValue := map[string]string{
"name": "吴用",
"age": "44",
}
map1 = append(map1, mapValue)
fmt.Println(map1)
}
运行结果:
[map[age:45 name:宋江] map[age:40 name:卢俊义] map[age:44 name:吴用]]
map 细节
map是引用类型,遵守引用类型传递的机制,在一个函数中接受map,修改后,会直接修改原来的map
package main
import "fmt"
func modifyMap(map1 map[int]int) {
map1[10] = 200
}
func main() {
// map 函数值传递的演示
map1 := map[int]int{
1: 11,
2: 22,
10: 100,
}
fmt.Println(map1)
modifyMap(map1) // 调函数后,会修改原下标10的值
fmt.Println(map1)
}
map可以自动扩容,并不会报panic,这点和切片不同(切片超过容量必须使用append)
package main
import "fmt"
func main() {
// map 自动扩容的演示
map1 := make(map[int]int, 2) // 定义2个容量
map1[1] = 11
map1[2] = 22
map1[3] = 33 // 超过2个容量会自动扩容,不会报panic
map1[4] = 44
fmt.Println(map1)
}
map的value经常使用结构体struct类型,更灵活,也更适合管理复杂的数据
package main
import "fmt"
type Stu struct {
Name string
Age int
Score float32
}
func main() {
// map struct类型的演示
stuents := make(map[string]Stu)
stu1 := Stu{"宋江", 18, 67.00}
stu2 := Stu{"卢俊义", 19, 50.50}
stu3 := Stu{"吴用", 20, 99.00}
stuents["no1"] = stu1
stuents["no2"] = stu2
stuents["no3"] = stu3
for i, v := range stuents {
fmt.Printf("学生编号:%v,名字:%v,年龄:%v,分数:%v\n", i, v.Name, v.Age, v.Score)
}
}
课堂练习
要求:
使用map[string]map[string]string类型
key是唯一的,不可以重复
如果某个用户存在,修改他的密码为:888888;如果不存在新增用户
package main
import "fmt"
func modifyPwd(users map[string]map[string]string, name string) {
exists := false
for i, v := range users {
if v["name"] == name {
users[i]["pwd"] = "888888"
exists = true
}
}
if !exists {
users["no3"] = map[string]string{
"name": name,
"pwd": "888888",
}
}
}
func main() {
users := make(map[string]map[string]string)
user1 := map[string]string{
"name": "tom",
"pwd": "123456",
}
user2 := map[string]string{
"name": "mary",
"pwd": "987654",
}
users["no1"] = user1
users["no2"] = user2
modifyPwd(users, "lily")
fmt.Println(users)
}
运行结果:
map[no1:map[name:tom pwd:123456] no2:map[name:mary pwd:987654] no3:map[name:lily pwd:888888]]