Go语言中的map(映射、字典)是一种内置的数据结构,它是一个无序的key
-value
对的集合。
Go语言中的map是引用类型,必须初始化才能使用。
一、map的定义和初始化
go语言中map声明的语法:
var m = map[keyType]valueType
其中:keyType-键key的类型
valueType-值value的类型
package main
import "fmt"
func main() {
var m map[int]string
fmt.Println(m)
fmt.Println(m == nil)
m[1] = "tom"
fmt.Println(m)
}
运行结果
map[]
true
panic: assignment to entry in nil map
goroutine 1 [running]:
main.main()
E:/golang/go_project/main.go:9 +0x107
exit status 2
但这样声明的map的初始值为nil,是不能存放键值对,需要使用make()
函数类分配内存。
m = make([keyType]valueType, [cap])
其中:cap-表示map的容量,非必须,但建议初始化时指定一个合适的容量。
package main
import "fmt"
func main() {
var m map[int]string
m = make(map[int]string, 10)
fmt.Println(m)
fmt.Println(m == nil)
m[1] = "tom"
fmt.Println(m)
}
运行结果
map[]
false
map[1:tom]
也可以直接声明和赋值
var m = map[keyType]valueType {
key: value,
key: value,
}
package main
import "fmt"
func main() {
m := map[int]string{
1: "tom",
2: "jack",
}
fmt.Println(m)
}
运行结果
map[1:tom 2:jack]
二、map的操作
1、添加
map[key] = value
注意:
- map里所有key的数据类型必须是相同的,value的数据类型也必须相同,但key和value的数据类型可以不相同
- map里key可以是所有可比较的类型,如布尔型、整数型、浮点型、复杂型、字符串型等
- map里key是唯一的,后添加的key-value,会覆盖前面的key-value
package main
import "fmt"
func main() {
m := make(map[int]string, 10)
m[1] = "tom"
m[2] = "jack"
fmt.Println(m)
m[1] = "lili"
fmt.Println(m)
}
运行结果
map[1:tom 2:jack]
map[1:lili 2:jack]
2、取值
map[key] 可以获得key对应的value值
但是当key如果不存在的时候,我们会得到该value值类型的默认值,比如string类型得到空字符串,int类型得到0。但是程序不会报错。
所以我们可以使用ok-idiom获取值,可知道key/value是否存在
value, ok := map[key]
package main
import "fmt"
func main() {
m := make(map[int]string, 10)
m = map[int]string{
1: "tom",
2: "jack",
}
fmt.Println(m[3]) // 返回string的默认值""
v, ok := m[3]
if ok {
fmt.Println("3-", v)
} else {
fmt.Println("查无此人!")
}
}
运行结果
查无此人!
3、删除
使用delete()
内建函数从map中删除一组键值对,如果key存在则删除,如果key不存在则不做任何操作也不报错
delete(map, key)
其中:map-表示要删除键值对的map
key-表示要删除的键值对的键
package main
import "fmt"
func main() {
m := make(map[int]string, 10)
m = map[int]string{
1: "tom",
2: "jack",
}
delete(m, 2)
delete(m, 3)
fmt.Println(m)
}
运行结果
map[1:tom]
4、遍历
go语言中使用for range遍历map,遍历的结果是无序的。
package main
import "fmt"
func main() {
m := make(map[int]string, 10)
m = map[int]string{
1: "tom",
2: "jack",
3: "lili",
4: "marry",
}
for k, v := range m {
fmt.Printf("%v-%v\t", k, v)
}
}
运行结果
3-lili 4-marry 1-tom 2-jack
5、map的长度
len(map)可以获取map的长度
两个map也是不能进行比较的,map唯一可以合法比较的对象是nil map can only be compared to nil
因此应该应len(map) == 0
来判断map是否为空
三、map的注意事项
1、map是引用类型
go语言中和切片一样,map也是引用数据类型,赋值和传参都是浅拷贝,传递的是map的地址。它们都指向相同的内部数据结构,因此,一个的变化会反映到另一个。
package main
import "fmt"
func main() {
m := make(map[int]string, 10)
m = map[int]string{
1: "tom",
2: "jack",
3: "lili",
4: "marry",
}
m2 := m
m2[2] = "小小强"
fmt.Println(m) //map[1:tom 2:小小强 3:lili 4:marry]
fmt.Println(m2) //map[1:tom 2:小小强 3:lili 4:marry]
test(m)
fmt.Println(m) //map[1:小强 2:小小强 3:lili 4:marry]
}
func test(m map[int]string) {
m[1] = "小强"
}
运行结果
map[1:tom 2:小小强 3:lili 4:marry]
map[1:tom 2:小小强 3:lili 4:marry]
map[1:小强 2:小小强 3:lili 4:marry]
2、map&slice
map和slice结合使用,可以是
- slice的元素为一个map类型
package main
import "fmt"
func main() {
m1 := make(map[string]string, 2)
m1 = map[string]string{
"name": "tom",
"address": "上海市",
}
m2 := make(map[string]string, 4)
m2 = map[string]string{
"name": "jack",
"address": "北京市",
}
m3 := make(map[string]string, 6)
m3 = map[string]string{
"name": "marry",
"address": "苏州市",
}
s := make([]map[string]string, 3, 10)
s = []map[string]string{m1, m2, m3}
fmt.Println(s)
for k1, v1 := range s {
fmt.Printf("第%v个人信息:\n", k1+1)
for k2, v2 := range v1 {
fmt.Printf("\t%v:%v\n", k2, v2)
}
}
}
运行结果
[map[address:上海市 name:tom] map[address:北京市 name:jack] map[address:苏州市 name:marry]]
第1个人信息:
name:tom
address:上海市
第2个人信息:
name:jack
address:北京市
第3个人信息:
address:苏州市
name:marry
- map的value为一个slice类型
package main
import "fmt"
func main() {
m := make(map[string][]int, 2)
m = map[string][]int{
"tom": []int{80, 98, 95},
"jack": []int{94, 87, 91},
}
fmt.Println(m)
}
运行结果
map[jack:[94 87 91] tom:[80 98 95]]
网友评论