map
一、map的定义
map是key-value数据结构,又称为字段或者关联数组。
map的声明:
var map的变量名 map[keytype] valuetype
key的数据类型:golang中map的key可以是很多种类型,比如bool,数字,string,指针,channel,还可以是只包含前面几个类型的接口,结构体,数组。通常key为int、string
注意:slice,map还有function不可以,因为这几个没法用==来判断。
valuetype的类型:
valuetype的类型和key基本一样。通常为:数字(整数,浮点数),string,map,struct。
map声明的举例:
var a map[string]string
var a map[string]int
var a map[int]string
var a map[string]map[string]string
注意:声明是不会分配内存的,初始化需要make ,分配内存后才能赋值和使用。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | package main import "fmt" func main() { var a map [string]string a = make( map [string]string, 10) a[ "no1" ] = "songjiang" a[ "no2" ] = "wuyong" a[ "no3" ] = "wusong" a[ "no1" ] = "wuyong" fmt.Println(a) } |
map在使用前一定要make
map的key是不能重复,如果重复了,则以最后这个key-value为准
map的value是可以相同的.
map的key-value是无序
make内置函数数目
func make(Type, size IntegerType) Type
内建函数make分配并初始化一个类型为切片、映射、或通道的对象。其第一个实参为类型,而非值。make的返回类型与其参数相同,而非指向它的指针。其具体结果取决于具体的类型:
切片:size指定了其长度。该切片的容量等于其长度。切片支持第二个整数实参可用来指定不同的容量;
它必须不小于其长度,因此 make([]int, 0, 10) 会分配一个长度为0,容量为10的切片。
映射:初始分配的创建取决于size,但产生的映射长度为0。size可以省略,这种情况下就会分配一个小的起始大小。
通道:通道的缓存根据指定的缓存容量初始化。若 size为零或被省略,该信道即为无缓存的。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 | package main import "fmt" func main() { studentMap := make( map [string] map [string]string) studentMap[ "stu01" ] = make( map [string]string, 3) studentMap[ "stu01" ][ "name" ] = "tom" studentMap[ "stu01" ][ "sex" ] = "男" studentMap[ "stu01" ][ "address" ] = "北京长安街~" studentMap[ "stu02" ] = make( map [string]string, 3) studentMap[ "stu02" ][ "name" ] = "mary" studentMap[ "stu02" ][ "sex" ] = "女" studentMap[ "stu02" ][ "address" ] = "上海浦东" fmt.Println(studentMap) fmt.Println(studentMap[ "stu02" ]) fmt.Println(studentMap[ "stu01" ][ "address" ]) } |
二、map的增删改查操作
1、map的增加和更新
如果key还没有就算增加,如果key已经存在就是修改。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | package main import "fmt" func main() { cities := make( map [string]string) cities[ "no1" ] = "北京" cities[ "no2" ] = "天津" cities[ "no3" ] = "上海" fmt.Println(cities) cities[ "no3" ] = "深圳~" fmt.Println(cities) } |
2、map的删除
delete(map,"key") ,delete是一个内置函数,如果key存在,就删除该key-value,如果key不存在,不操作,但是也不会报错。
func delete(m map[Type]Type1, key Type)
内建函数delete按照指定的键将元素从映射中删除。若m为nil或无此元素,delete不进行操作。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 | package main import "fmt" func main() { cities := make( map [string]string) cities[ "no1" ] = "北京" cities[ "no2" ] = "天津" cities[ "no3" ] = "上海" fmt.Println(cities) cities[ "no3" ] = "深圳~" fmt.Println(cities) delete(cities, "no1" ) fmt.Println(cities) delete(cities, "no5" ) fmt.Println(cities) } |
如果我们要删除map的所有key ,没有一个专门的方法一次删除,可以遍历一下key, 逐个删除或者map = make(...),make一个新的,让原来的成为垃圾,被gc回收。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | package main import "fmt" func main() { cities := make( map [string]string) cities[ "no1" ] = "北京" cities[ "no2" ] = "天津" cities[ "no3" ] = "上海" fmt.Println(cities) cities = make( map [string]string) fmt.Println(cities) } |
3、map的查找
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 | package main import "fmt" func main() { cities := make( map [string]string) cities[ "no1" ] = "北京" cities[ "no2" ] = "天津" cities[ "no3" ] = "上海" fmt.Println(cities) val, ok := cities[ "no2" ] if ok { fmt.Printf( "键no2的值为%v\n" , val) } else { fmt.Printf( "没有键为no2" ) } } |
三、map的遍历
map的遍历使用for-range的结构遍历
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 | package main import "fmt" func main() { cities := make( map [string]string) cities[ "no1" ] = "北京" cities[ "no2" ] = "天津" cities[ "no3" ] = "上海" fmt.Println(cities) for k, v := range cities { fmt.Printf( "key = %v value = %v\n" , k, v) } studentMap := make( map [string] map [string]string) studentMap[ "stu01" ] = make( map [string]string, 3) studentMap[ "stu01" ][ "name" ] = "tom" studentMap[ "stu01" ][ "sex" ] = "男" studentMap[ "stu01" ][ "address" ] = "北京长安街~" studentMap[ "stu02" ] = make( map [string]string, 3) studentMap[ "stu02" ][ "name" ] = "mary" studentMap[ "stu02" ][ "sex" ] = "女" studentMap[ "stu02" ][ "address" ] = "上海浦东" for k1, v1 := range studentMap { fmt.Printf( "key1 = %v value2 = %v" , k1, v1) for k2, v2 := range v1 { fmt.Printf( "\t key2 = %v value2 = %v\n" , k2, v2) } fmt.Println() } } |
四、map的长度
func len(v Type) int
内建函数len返回v的长度,这取决于具体类型:
数组:v中元素的数量
数组指针:*v中元素的数量(v为nil时panic)
切片、映射:v中元素的数量;若v为nil,len(v)即为零
字符串:v中字节的数量
通道:通道缓存中队列(未读取)元素的数量;若v为nil,len(v)即为零
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 | package main import "fmt" func main() { cities := make( map [string]string) cities[ "no1" ] = "北京" cities[ "no2" ] = "天津" cities[ "no3" ] = "上海" fmt.Println(len(cities)) studentMap := make( map [string] map [string]string) studentMap[ "stu01" ] = make( map [string]string, 3) studentMap[ "stu01" ][ "name" ] = "tom" studentMap[ "stu01" ][ "sex" ] = "男" studentMap[ "stu01" ][ "address" ] = "北京长安街~" studentMap[ "stu02" ] = make( map [string]string, 3) studentMap[ "stu02" ][ "name" ] = "mary" studentMap[ "stu02" ][ "sex" ] = "女" studentMap[ "stu02" ][ "address" ] = "上海浦东" fmt.Println(len(studentMap)) } |
五、map切片
切片的数据类型如果是map,则我们称为slice of map,map切片,这样使用则map个数就可以动态变化了。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 | package main import "fmt" func main() { var monsters [] map [string]string monsters = make([] map [string]string, 2) if monsters[0] == nil { monsters[0] = make( map [string]string, 2) monsters[0][ "name" ] = "牛魔王" monsters[0][ "age" ] = "500" } if monsters[1] == nil { monsters[1] = make( map [string]string, 2) monsters[1][ "name" ] = "玉兔精" monsters[1][ "age" ] = "300" } //if monsters[2] == nil { // monsters[2] = make(map[string]string, 2) // monsters[2]["name"] = "蜘蛛精" // monsters[2]["age"] = "100" //} newMonster := map [string]string{ "name" : "新的妖怪" , "age" : "200" , } monsters = append(monsters, newMonster) fmt.Println(monsters) } |
六、map的排序
golang中没有一个专门的方法针对map的key进行排序
golang中的map默认是无序的,注意也不是按照添加的顺序存放的,你每次遍历,得到的输出可能不一样
golang中map的排序,是先将key进行排序,然后根据key值遍历输出即可
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 | package main import ( "fmt" "sort" ) func main() { //map的排序 m := make( map [int]int, 10) m[10] = 100 m[1] = 13 m[4] = 56 m[8] = 90 fmt.Println(m) //如果按照map的key的顺序进行排序输出,则先将map的key放入切片中,对切片进行排序,遍历切片,然后按照key来输出map的值 var keys []int for k, _ := range m { keys = append(keys, k) } sort.Ints(keys) fmt.Println(keys) for _, k := range keys { fmt.Printf( "m[%v] = %v\n" , k, m[k]) } } |
七、map使用的注意事项
1、map是引用类型,遵守引用类型传递的机制,在一个函数接收map,修改后,会直接修改原来的map
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 | package main import "fmt" func modify(m map [int]int) { m[50] = 100 } func main() { m := make( map [int]int) m[1] = 90 m[2] = 78 m[10] = 1 m[20] = 3 fmt.Println( "map修改前" , m) modify(m) fmt.Println( "map修改后" , m) } |
2、map的容量达到后,再想map增加元素,会自动扩容,并不会发生panic,也就是说map能动态的增长键值对(key-value)
3、map的value也经常使用struct类型,更适合管理复杂的数据(比value是一个map更好)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 | package main import "fmt" func modifyUser(users map [string] map [string]string, name string) { if users[name] != nil { users[name][ "pwd" ] = "888888" } else { users[name] = make( map [string]string, 2) users[name][ "pwd" ] = "888888" users[name][ "nickname" ] = "这是我的昵称:" + name } } func main() { //使用 map[string]map[string]sting 的map类型 //key: 表示用户名,是唯一的,不可以重复 //如果某个用户名存在,就将其密码修改"888888",如果不存在就增加这个用户信息,(包括昵称nickname 和 密码 pwd)。 //编写一个函数modifyUser(users map[string]map[string]sting, name string)完成上述功能 users := make( map [string] map [string]string, 10) users[ "smith" ] = make( map [string]string, 2) users[ "smith" ][ "pwd" ] = "999999" users[ "smith" ][ "nickname" ] = "小狗" modifyUser(users, "tom" ) modifyUser(users, "mary" ) modifyUser(users, "smith" ) fmt.Println(users) } |
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】凌霞软件回馈社区,博客园 & 1Panel & Halo 联合会员上线
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】博客园社区专享云产品让利特惠,阿里云新客6.5折上折
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 用 C# 插值字符串处理器写一个 sscanf
· Java 中堆内存和栈内存上的数据分布和特点
· 开发中对象命名的一点思考
· .NET Core内存结构体系(Windows环境)底层原理浅谈
· C# 深度学习:对抗生成网络(GAN)训练头像生成模型
· 为什么说在企业级应用开发中,后端往往是效率杀手?
· 本地部署DeepSeek后,没有好看的交互界面怎么行!
· 趁着过年的时候手搓了一个低代码框架
· 用 C# 插值字符串处理器写一个 sscanf
· 推荐一个DeepSeek 大模型的免费 API 项目!兼容OpenAI接口!