golang map

1.声明

var 变量名 map[keytype]valuetype

golang中的map的key可以是很多类型,比如bool,数字,string,指针,channel还可以是前面几个类型的接口,结构体,数组,通常为int,string。

注意:

1.slice,map还有function不可以做key,因为这几个没法用==来判断。

2.声明是不会分配内存的,初始化需要make,分配内存后才能赋值和使用,若size省略则会分配一个小的起始大小。但是size是随着使用而自动增加的。

3.map的key是不可以重复的,如果重复了,则后面的值会覆盖前面的值

3.golang的map中的元素是无序的

 

复制代码
func main() {  
//map的声明和注意事项 var a map[string]string //在使用map前,需要先make,make的作用就是给mao分配数据空间,下面分配了10个长度
a = make(map[string]string, 10) //map[no1:武松 no2:吴用 no3:吴用] a["no1"] = "宋江" a["no2"] = "吴用" a["no1"] = "武松" //替换掉了"宋江" a["no3"] = "吴用" fmt.Println(a) }
复制代码

2.使用

1)声明+make

var cities map[string]string

cities = map(map[string]string, 10)

2)声明时make

var cities = make(map[string]string, 10)

3)声明,直接赋值

var cities map[string]string = map[string]string{"node4":成都}

cities["no1"] = "成都"

复制代码
func main() {
    //第一种方式
    //map的声明和注意事项
    var a map[string]string
    //在使用map前,需要先make,make的作用就是给mao分配数据空间
    a = make(map[string]string, 10)
    //map[no1:武松 no2:吴用 no3:吴用]
    a["no1"] = "宋江"
    a["no2"] = "吴用"
    a["no1"] = "武松" //替换掉了"宋江"
    a["no3"] = "吴用"
    fmt.Println(a)

    //第二种方式
    cities := make(map[string]string)
    cities["no1"] = "北京"
    cities["no2"] = "添加"
    cities["no3"] = "上海"
    fmt.Println(cities)

    //第三种方式
    //heroes := map[string]string{
    var heroes map[string]string = map[string]string{
        "her01": "宋江",
        "hero2": "卢俊义",
    }
    heroes["hero3"] = "吴用"
    fmt.Println(heroes)
}
复制代码

3.map实例

要存放3个学生信息,每个学生有name,sex和adress信息

思路:key为学号,val为map[string]string,其中val的map中存放的是name,sex和adress

复制代码
func std() {
    student := make(map[string]map[string]string)

    student["stu01"] = make(map[string]string, 3)
    student["stu01"]["name"] = "tom"
    student["stu01"]["sex"] = ""
    student["stu01"]["address"] = "北京长安街"

    student["stu02"] = make(map[string]string, 3)
    student["stu02"]["name"] = "jack"
    student["stu02"]["sex"] = ""
    student["stu02"]["address"] = "上海长安街"

    fmt.Println(student)
    fmt.Println(student["stu02"])
    fmt.Println(student["stu02"]["address"])
}
复制代码

4.map的增删改查crud

复制代码
func crud() {
    cities := make(map[string]string)
    //1.增加
    cities["no1"] = "北京"
    cities["no2"] = "添加"
    cities["no3"] = "上海"

    //2.修改:因为no3这个key已经存在了,所以下面这句话就是修改
    cities["no3"] = "上海~"
    fmt.Println(cities)

    //3.查找
    //如果找到了,findRes为true,找不到为false
    val, findRes := cities["no3"]
    if findRes {
        fmt.Printf("有no3这个key,值为%v:\n", val)
    } else {
        fmt.Println("没有no3这个key\n")
    }
    
    //4.删除,delete函数删除元素
    delete(cities, "no1")
    fmt.Println(cities)
    //当delete指定的key不存在,删除不会操作,也不会报错
    delete(cities, "node4")
    fmt.Println(cities)
    //如果要删除map中所有的key,没有专门的函数
    //1)可以遍历key逐个删除
    //2)给map make一个新的空间,让原本的成为垃圾被gc回收
    cities = make(map[string]string)
    fmt.Println(cities)
}
复制代码

5.map的遍历

由于map的key不一定是数字通常为string,所以不适应for循环,而使用for-range来遍历

复制代码
func xh() {
    //简单结构map的for-range
    cities := make(map[string]string)
    cities["no1"] = "北京"
    cities["no2"] = "添加"
    cities["no3"] = "上海"

    for k, v := range cities {
        fmt.Printf("k=%v,v=%v\n", k, v)
    }
    //使用双层for-range遍历一个结构比较复杂的map
    student := make(map[string]map[string]string)

    student["stu01"] = make(map[string]string, 3)
    student["stu01"]["name"] = "tom"
    student["stu01"]["sex"] = ""
    student["stu01"]["address"] = "北京长安街"

    student["stu02"] = make(map[string]string, 3)
    student["stu02"]["name"] = "jack"
    student["stu02"]["sex"] = ""
    student["stu02"]["address"] = "上海长安街"

    for k1, v1 := range student {
        fmt.Println("k1=", k1)
        for k2, v2 := range v1 {
            fmt.Printf("\t k2=%v v2=%v\n", k2, v2)
        }
    }
}
复制代码

6.map切片

使用map切片,使map的个数可以动态变化,效果相当于一个复合map   map[int]map[string]string,但是复合map只是一个map而map切片是有多个map

案例:使用一个map来记录monster的信息name和age,也就是说一个monster对应一个map,并且妖怪的个数是可以动态增加的=>map切片

 

复制代码
func mons() {
    var monsters []map[string]string
    //切片本身要make一次,切片make时必须要加长度
    monsters = make([]map[string]string, 2)

    if monsters[0] == nil {
        //切片的数据类型为map,map还需要make一次,map make时可以不加长度
        monsters[0] = make(map[string]string)
        monsters[0]["name"] = "牛魔王"
        monsters[0]["age"] = "500"
    }
    if monsters[1] == nil {
        //切片的数据类型为map,map还需要make一次,map make时可以不加长度
        monsters[1] = make(map[string]string, 2)
        monsters[1]["name"] = "玉兔精"
        monsters[1]["age"] = "300"
    }
    //切片数量的动态增加用append(slice,map)
    newmonsters := map[string]string{
        "name": "火云邪神",
        "age":  "600",
    }
    monsters = append(monsters, newmonsters)
    fmt.Println(monsters) //[map[age:500 name:牛魔王] map[age:300 name:玉兔精]]

}
复制代码

7. map排序

1)golang中没有专门的方法针对map的key进行排序

2)golang中的map默认是无序的,注意也不是按照添加的顺序放的,每次遍历,得到的输出可能都不一样

3)要做map的排序,需要先将key进行排序,然后根据key的值遍历输出即可

复制代码
func sortmap() {
    //map的排序
    map1 := make(map[int]int, 4)
    map1[10] = 100
    map1[1] = 13
    map1[4] = 56
    map1[2] = 90
    fmt.Println(map1)
    //按照map的key的顺序进行排序输出
    //1.先将map的key放入到切片中
    //2.对切片排序
    //3.遍历切片,然后按照key来输出map的值
    //建立key的map切片
    var keys []int
    for key, _ := range map1 {
        keys = append(keys, key)
    }
    //对keys进行排序
    sort.Ints(keys)
    //遍历切片,按照key输出map值
    for _, v := range keys {
        fmt.Printf("%v", map1[v])
    }
}
复制代码

8.map的使用细节

1)map是引用类型,遵守引用类型传递的机制,在一个函数接收map,修改后会直接修改原来的map

2)map容量达到后,map再增加元素,会自动扩容,并不会发生panic,也就是说map能动态的增长键值对。而数组,只能通过append函数进行扩容而不能自动扩容

3)map的value也经常使用struct类型,更适合管理复杂的数据(比前面value是一个map更好),比如valur为student结构体

复制代码
type Stu struct {
    Name    string
    Age     int
    Address string
}
func f1() {
    students := make(map[string]Stu, 10)
    stu1 := Stu{"tom", 18, "北京"}
    stu2 := Stu{"marry", 16, "上海"}
    students["no1"] = stu1
    students["no2"] = stu2
    fmt.Println(students)
    //遍历
    for k, v := range students {
        fmt.Printf("学生的编号是%v\t", k)
        fmt.Printf("学生的名字是%v\t", v.Name)
        fmt.Printf("学生的年龄是%v\t", v.Age)
        fmt.Printf("学生的地址是%v\t", v.Address)
        fmt.Println()
    }
}
复制代码

 9.使用map[string]map[string]string的map类型;key表示用户名,是唯一的不可用重复;如果某个用户名存在,就将其密码修改为“888888”,如果不存在就增加这个用户信息(包括昵称nickname和密码pwd);编写一个函数modifyuser(users map[string]map[string]string, name string)完成上述功能

复制代码
func modifyUser(user map[string]map[string]string, name string) {

    if user[name] != nil {
        user[name]["pwd"] = "888888"
    } else {
        user[name] = make(map[string]string, 2)
        user[name]["nockname"] = "昵称!" + name
        user[name]["pwd"] = "777"
    }
}
func main() {
    user := make(map[string]map[string]string, 2)
    user["smth"] = make(map[string]string, 2)
    user["smth"]["nockname"] = "smth"
    user["smth"]["pwd"] = "9999"
    modifyUser(user, "TOM")
    modifyUser(user, "Marry")
    modifyUser(user, "Marry1")
    modifyUser(user, "Marry2")
    modifyUser(user, "smth")
    fmt.Println(user)
}
复制代码

 

posted @   潇潇暮鱼鱼  阅读(46)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· DeepSeek 开源周回顾「GitHub 热点速览」
· 物流快递公司核心技术能力-地址解析分单基础技术分享
· .NET 10首个预览版发布:重大改进与新特性概览!
· AI与.NET技术实操系列(二):开始使用ML.NET
· 单线程的Redis速度为什么快?
点击右上角即可分享
微信分享提示