目录
一、什么是map
-
map
是相当于python中的字典,是一群键值对的集合体,可以通过键来取值、改值、增值 -
python在3.7版本之前字典是无序的,但是在之后的版本都是有序的,即按照插入顺序排列键值对,而Go中的map是无序的
-
不同的是,Go中所有可比较的类型
boolean,interger,float,complex,string
等,都可以作为map
的key -
空map
的零值是nil
,map
之间不能使用==
操作符判断,只能用来检查map
是否为nil
-
package main import ( "fmt" ) func main() { var personSalary map[string]int // 同 personSalary := make(map[string]int) if personSalary == nil { // 为真 fmt.Println("map is nil. Going to make one.") personSalary = make(map[string]int) } }
-
二、map
的创建
- 两种创建方式
1. 直接创建
1. 声明一个map类型,此时该map 等于 nil ,只要初始化了,就不等于 nil
var map名 map[key类型]值类型
2. 定义一个map,并初始化,{}内元素为0个时,此时map也不等于 nil
var map名 = map[key类型]值类型{key1:val1,key2:val2 等等} // {} 内键值对为0到无数个
map名 := map[key类型]值类型{key1:val1,key2:val2 等等} // {} 内键值对为0到无数个
// 示例
personSalary := make(map[string]int) // 同 var personSalary = map[string]int{} ,同 personSalary := map[string]int{}
personSalary := map[string]int {
"steve": 12000,
"jamie": 15000,
}
2. 通过make函数创建
var map名 = make(map[key类型]值类型)
map名 := make(map[key类型]值类型)
// 示例:
var personSalary = make(map[string]int)
personSalary := make(map[string]int)
三、map
的取值、改值、增值
- 取值的语法和python的字典取值是一样的,即
map名[key]
- 当取值时,
map
中不存在这个key,程序不会报错,而是返回一个该值类型的空值
1. 取值、改值、增值实例
package main
import (
"fmt"
)
func main() {
personSalary := map[string]int{
"steve": 12000,
"jamie": 15000,
}
personSalary["mike"] = 9000 // 新增 mike:9000 的键值对
personSalary["steve"] = 11000 // 修改 steve的值为11000
employee := "jamie"
fmt.Println(personSalary[employee]) // 15000
fmt.Println(personSalary["steve"]) // 11000
fmt.Println(personSalary["joe"]) // 0
}
2. 判断key是否存在
语法:
value, res := map名[key]
// 若key存在,则 res值为 true,此时value为key对应的值
// 若key不存在,则 res值为 false,此时value为该map值类型的空值
四、for range
遍历map
for range
遍历map
时,返回的是key和value
package main
import (
"fmt"
)
func main() {
personSalary := map[string]int{
"steve": 12000,
"jamie": 15000,
}
personSalary["mike"] = 9000
fmt.Println("All items of a map")
for key, value := range personSalary {
fmt.Printf("personSalary[%s] = %d\n", key, value)
}
}
/*
输出结果
All items of a map
personSalary[mike] = 9000
personSalary[steve] = 12000
personSalary[jamie] = 15000
*/
五、删除 map
中的元素
- 使用
delete(map,key)
方法进行删除,该方法没有返回值 - 删除一个不存在的key,不会报错
package main
import (
"fmt"
)
func main() {
personSalary := map[string]int{
"steve": 12000,
"jamie": 15000,
}
personSalary["mike"] = 9000
fmt.Println("map before deletion", personSalary)
delete(personSalary, "steve")
fmt.Println("map after deletion", personSalary)
delete(personSalary, "111") // 删除一个不存在的key,不会报错
fmt.Println("map after deletion", personSalary)
}
/*
打印结果
map before deletion map[jamie:15000 mike:9000 steve:12000]
map after deletion map[jamie:15000 mike:9000]
map after deletion map[jamie:15000 mike:9000]
*/
六、获取 map
的长度
- 使用
len
函数
package main
import (
"fmt"
)
func main() {
personSalary := map[string]int{
"steve": 12000,
"jamie": 15000,
}
personSalary["mike"] = 9000
fmt.Println("length is", len(personSalary)) // length is 3
}
七、map
是引用类型
- 和切片类似,
map
也是引用类型。当map
被赋值为一个新变量的时候,它们指向同一个内部数据结构。因此,改变其中一个变量,就会影响到另一变量 - 当
map
作为函数参数传递时也会发生同样的情况。函数中对map
的任何修改,对于外部的调用都是可见的
package main
import (
"fmt"
)
func main() {
personSalary := map[string]int{
"steve": 12000,
"jamie": 15000,
}
personSalary["mike"] = 9000
fmt.Println("Original person salary", personSalary)
newPersonSalary := personSalary // 此时,newPersonSalary 和 personSalary 指向的都是同一个map
newPersonSalary["mike"] = 18000
fmt.Println("Person salary changed", personSalary)
}
/*
Original person salary map[steve:12000 jamie:15000 mike:9000]
Person salary changed map[steve:12000 jamie:15000 mike:18000]
*/
八、多类型value的 map
map
的value部分可以是任意类型,数字、字符串、数组、切片、map
等
1. 复杂 map
的定义
1. 定义一个复杂map
var a = make(map[int]map[int]string) // 定义一个value也为map的map
var b = make(map[string]map[string]string) // 定义一个value也为map的map
var c = make(map[int][3]string) // 定义一个value为数组的map
var d = make(map[string][]int) // 定义一个value为切片的map
a := make(map[int]map[int]string) // 定义一个value也为map的map
b := make(map[string]map[string]string) // 定义一个value也为map的map
c := make(map[int][3]string) // 定义一个value为数组的map
d := make(map[string][]int) // 定义一个value为切片的map
// ************上面这些定义只是定义了第一层value为其他数据类型,还可以定义第二层,第三层等等************
// ************ 因为map的value类型是定义时就确定好的,所以,不能像python一样,中途通过键增值其他的数据类型,因此只能事先定义好要用的那一层的value的类型
2. 复杂 map
的赋值
- 分为 内部的
map、切片
赋值 和数组
赋值两种情况
(1)内部的map、切片
赋值
package main
import (
"fmt"
)
func main() {
a := make(map[int]map[int]string) // 初始化一个第一层value为map的 map
var b = make(map[string]map[string]string) // 初始化一个第一层value为map的 map
var c = make(map[int][3]string) // 初始化一个第一层value为数组的map
var d = make(map[string][]int) // 初始化一个第一层value为切片的map
fmt.Println(a) // map[]
fmt.Println(b) // map[]
fmt.Println(c) // map[]
fmt.Println(d) // map[]
if a == nil {
println("111") // 未打印
} else {
println("222") // 222
}
if a[1] == nil {
println("333") // 333
}
// a[1][2] = "sss"
/*
不能直接进行赋值操作,会报错: panic: assignment to entry in nil map ,
因为此时a[1]对应的值相当于声明了一个map类型,未初始化,所以它的值为 nil,nil是不能进行map的增值操作的,
必须先将 a[1] 对应的map 初始化,
如下面的 a[1] = map[int]string{}
d 的value是切片,和上面 a 同理,也要先初始化,再进行赋值
*/
// fmt.Println("444", a)
a[1] = map[int]string{}
a[1][2] = "sss"
fmt.Println("555", a) // 555 map[1:map[2:sss]]
}
(2)内部数组的赋值
- 待更