持续创作,加速成长!这是我参与「掘金日新计划 · 6 月更文挑战」的第12天,点击查看活动详情
🎐 放在前面说的话
大家好,我是沥沥樱 👧🏻
本科在读,此为日常捣鼓.
如有不对,请多指教,也欢迎大家来跟我讨论鸭 👏👏👏
还有还有还有很重要的,麻烦大可爱们动动小手,给沥沥樱点颗心心♥,沥沥樱需要鼓励嗷呜~
emmm....之前一直听别人说map map自己也用过,但是并不知道具体是干嘛的,只知道是集合的意思,可能大家会觉得搞笑,这不是基础么?怎么会有搞代码的人不知道呢?没关系,我就是那个人,今天我就来学一下map
Let’s get it!
map
map概念
- map是一种通过key来获取value的一个数据结构,其底层存储方式为数组,在存储时key不能重复,当key重复时,value进行覆盖,又被称为字段或者关联数组
- map在程序设计中经常使用,且作为一种最基础的数据结构,很多编程语言本身提供的api都会有实现
声明方式
声明是不会分配内存的,需要用make初始化分配内存,分配内存后才能被赋值和使用
var map变量名 map[key类型]value类型
key 支持类型
- bool
- int
- string
- channel
- 指针
- 接口、结构体、数组等
value 支持类型
和key基本一样,常用的有:
- string
- map
- struct
- int等数字类型
举例:
var a map[string]int
var b map[int]string
var c map[string]map[string]string
栗子
func main() {
//map的声明和注意事项
var a map[string]string
//在使用map前,需要先make , make的作用就是给map分配数据空间
a = make(map[string]string, 10)
a["first"] = "小红"
a["second"] = "小米"
a["first"] = "沥沥樱"
a["fore"] = "小李"
fmt.Println(a)
}
打印: map[first:沥沥樱 fore:小李 second:小米]
栗子解说
- 声明后一定要先make才能使用map
- 内建函数make分配并且初始化一个类型为切片、映射或者通道的对象
func make(Type,size IntegerType) Type
- 映射:初始分配的创建取决于size,但是产生的映射长度为0.size可以省略,这种情况下就会分配一个小的起始大小
- 当key重复时,value进行覆盖
- value是可以重复的
- k-y存储是无序的
- make 内置函数项目
map 的两种使用方法
方式一
也就是我们上面用到的,比较常见的一种:
var a map[string]string
a = make(map[string]string,10)
方式二
sex := make(map[string]string)
sex["f1"] = "男孩子"
sex["fm2"] = "女孩子"
fmt.Println(sex)
map类型基本操作方法
go语言的map类型的初始化、添加、修改、删除、获取、自增、遍历、获取所有key到一个切片、按key排序、nil判等、切片类型转换为key、map作为函数参数等基本使用方法,废话不多说,直接用代码描述,直观,简单,易理解!
func main() {
// map 初始化1
map1 := make(map[string]bool)
fmt.Printf("map1 初始化:%v\n", map1)
//map 初始化2
map2 := map[string]int{
"php": 1,
"mysql": 2,
"go": 3,
}
fmt.Printf("map2 初始化:%v\n", map2)
//map 初始化3
var a map[string]string
//在使用map前,需要先make , make的作用就是给map分配数据空间
a = make(map[string]string, 10)
a["first"] = "小红"
a["second"] = "小米"
a["first"] = "沥沥樱"
a["fore"] = "小李"
fmt.Println(a)
//map 修改和添加
map3 := map[string]int{
"沥沥樱": 19,
"lisa": 26,
"北": 18,
}
map3["沥沥樱"] = 33 // 存在的key是修改
map3["小红"] = 6 // 不存在的key是添加
fmt.Printf("map3 修改和添加:%v\n", map3)
//map 删除
map4 := map[string]int{
"watermelon": 10,
"pear": 18,
"orange": 15,
}
delete(map4, "orange")
delete(map4, "banana") // key不存在也没关系
fmt.Printf("map4 删除:%v\n", map4)
//map 获取
map5 := map[string]int{
"rice": 33,
"bread": 2,
"milk": 1,
}
rice := map5["rice"] //能取到值 33
fmt.Printf("map5 获取: rice 能取到值: %d\n", rice)
juice := map5["juice"] //取不到,默认0值
fmt.Printf("map5 获取: juice 取不到值,默认0值: %d\n", juice)
//map 自增
map6 := map[string]int{
"yanwang": 1000,
}
map6["yanwang"]++
map6["xiaogui"]++ //默认0值也能自增
fmt.Printf("map6 自增: %v\n", map6)
//map 遍历,顺序不确定
map7 := map[string]int{
"tiger": 1,
"elephant": 1,
"monkey": 20,
"duck": 60,
}
fmt.Print("map7 遍历: ")
for k, v := range map7 {
fmt.Printf("键: %s, 值: %d\t", k, v)
}
//map 获取所有key到一个切片
map8 := map[string]int{
"Monday": 1,
"Tuesday": 2,
"Wednesday": 3,
"Thursday": 4,
"Friday": 5,
"Saturday": 6,
"Sunday": 7,
}
weeks := make([]string, 0, len(map8))
for d, _ := range map8 {
weeks = append(weeks, d)
}
fmt.Printf("map8 键集合: %v\n", weeks)
// 排序键集合
sort.Strings(weeks) //sort排序会改变参数
fmt.Printf("map8 排序后键集合: %v\n", weeks)
// 输出排序后map
fmt.Println("map8 排序后遍历:")
for _, d := range weeks {
fmt.Printf("%s: %d\t", d, map8[d])
}
fmt.Println()
// map的0值是nil
var map9 map[string]int
fmt.Printf("map9 == nil is: %t\n", map9 == nil)
// nil的map插入元素会异常,先创建再插入
//map9["insert"] = 10
map9 = map[string]int{}
map9["insert"] = 10
fmt.Printf("map9 nil创建后再插入: %v\n", map9)
// map 取值可以返回双值
map10 := map[string]int{
"January": 1,
"February": 2,
}
fmt.Printf("map10 : %v\n", map10)
January, ok1 := map10["January"]
fmt.Printf("map10 取双值,January:%v, ok: %v\n", January, ok1)
March, ok2 := map10["March"]
fmt.Printf("map10 取双值,March:%v, ok: %v\n", March, ok2)
// map 切片类型转换为 K
var map11 = make(map[string]int)
var list = []string{"hello"}
map11[k(list)] = 3
fmt.Printf("map11 切片类型转换为K: %v\n", map11)
// map 函数传参
var map12 = map[string]int{
"zhang": 15,
}
fmt.Printf("map12 原始值:%v\n", map12)
assign(map12)
fmt.Printf("map12 函数assign之后值:%v\n", map12)
modify(map12)
fmt.Printf("map12 函数modify之后值:%v\n", map12)
}
// 将切片转换为可判等类型
func k(list []string) string {
return fmt.Sprintf("%q", list)
}
// 通过赋值改变 map, 不起作用
func assign(m map[string]int) {
m = map[string]int{
"li": 16,
}
}
// 通过修改元素改变 map
func modify(m map[string]int) {
m["li"] = 16
}
打印:
map1 初始化:map[]
map2 初始化:map[go:3 mysql:2 php:1]
map[first:沥沥樱 fore:小李 second:小米]
map3 修改和添加:map[lisa:26 北:18 小红:6 沥沥樱:33]
map4 删除:map[pear:18 watermelon:10]
map5 获取: rice 能取到值: 33
map5 获取: juice 取不到值,默认0值: 0
map6 自增: map[xiaogui:1 yanwang:1001]
map7 遍历: 键: duck, 值: 60 键: tiger, 值: 1 键: elephant, 值: 1 键: monkey, 值: 20 \
map8 键集合: [Monday Tuesday Wednesday Thursday Friday Saturday Sunday]
map8 排序后键集合: [Friday Monday Saturday Sunday Thursday Tuesday Wednesday]
map8 排序后遍历:
Friday: 5 Monday: 1 Saturday: 6 Sunday: 7 Thursday: 4 Tuesday: 2 Wednesday: 3
map9 == nil is: true
map9 nil创建后再插入: map[insert:10]
map10 : map[February:2 January:1]
map10 取双值,January:1, ok: true
map10 取双值,March:0, ok: false
map11 切片类型转换为K: map[["hello"]:3]
map12 原始值:map[zhang:15]
map12 函数assign之后值:map[zhang:15]
map12 函数modify之后值:map[li:16 zhang:15]
🎉 放在后面说的话
以上总结了map的概念、使用,以及map类型的基本操作方法。