十七、Go基础编程:复合类型—map

1. 概述

Go语言中的map(映射、字典)是一种内置的数据结构,它是一个无序的key—value对的集合,比如以身份证号作为唯一键来标识一个人的信息。

map格式为:

 map[keyType]valueType

在一个map里所有的键都是唯一的,而且必须是支持==和!=操作符的类型,切片、函数以及包含切片的结构类型这些类型由于具有引用语义,不能作为映射的键,使用这些类型会造成编译错误:

dict := map[ []string ]int{} //err, invalid map key type []string

map值可以是任意类型,没有限制。map里所有键的数据类型必须是相同的,值也必须如何,但键和值的数据类型可以不相同。

注意:map是无序的,我们无法决定它的返回顺序,所以,每次打印结果的顺利有可能不同。

2. 创建和初始化

2.1 map的创建

   var m1 map[int]string  //只是声明一个map,没有初始化, 此为空(nil)map
    fmt.Println(m1 == nil) //true
    //m1[1] = "mike" //err, panic: assignment to entry in nil map

    //m2, m3的创建方法是等价的
    m2 := map[int]string{}
    m3 := make(map[int]string)
    fmt.Println(m2, m3) //map[] map[]

    m4 := make(map[int]string, 10) //第2个参数指定容量
    fmt.Println(m4)                //map[]

2.2 初始化 

   //1、定义同时初始化
    var m1 map[int]string = map[int]string{1: "mike", 2: "yoyo"}
    fmt.Println(m1) //map[1:mike 2:yoyo]

    //2、自动推导类型 :=
    m2 := map[int]string{1: "mike", 2: "yoyo"}
    fmt.Println(m2)

3. 常用操作

3.1 赋值

    m1 := map[int]string{1: "mike", 2: "yoyo"}
    m1[1] = "xxx"   //修改
    m1[3] = "lily"  //追加, go底层会自动为map分配空间
    fmt.Println(m1) //map[1:xxx 2:yoyo 3:lily]

    m2 := make(map[int]string, 10) //创建map
    m2[0] = "aaa"
    m2[1] = "bbb"
    fmt.Println(m2)           //map[0:aaa 1:bbb]
    fmt.Println(m2[0], m2[1]) //aaa bbb

 3.2 遍历

   m1 := map[int]string{1: "mike", 2: "yoyo"}
    //迭代遍历1,第一个返回值是key,第二个返回值是value
    for k, v := range m1 {
        fmt.Printf("%d ----> %s\n", k, v)
        //1 ----> mike
        //2 ----> yoyo
    }

    //迭代遍历2,第一个返回值是key,第二个返回值是value(可省略)
    for k := range m1 {
        fmt.Printf("%d ----> %s\n", k, m1[k])
        //1 ----> mike
        //2 ----> yoyo
    }

    //判断某个key所对应的value是否存在, 第一个返回值是value(如果存在的话)
    value, ok := m1[1]
    fmt.Println("value = ", value, ", ok = ", ok) //value =  mike , ok =  true

    value2, ok2 := m1[3]
    fmt.Println("value2 = ", value2, ", ok2 = ", ok2) //value2 =   , ok2 =  false

3.3 删除

    m1 := map[int]string{1: "mike", 2: "yoyo", 3: "lily"}
    //迭代遍历1,第一个返回值是key,第二个返回值是value
    for k, v := range m1 {
        fmt.Printf("%d ----> %s\n", k, v)
        //1 ----> mike
        //2 ----> yoyo
        //3 ----> lily
    }

    delete(m1, 2) //删除key值为2的map

    for k, v := range m1 {
        fmt.Printf("%d ----> %s\n", k, v)
        //1 ----> mike
        //3 ----> lily
    }

4. map做函数参数

在函数间传递映射并不会制造出该映射的一个副本,不是值传递,而是引用传递:

func DeleteMap(m map[int]string, key int) {
    delete(m, key) //删除key值为2的map

    for k, v := range m {
        fmt.Printf("len(m)=%d, %d ----> %s\n", len(m), k, v)
        //len(m)=2, 1 ----> mike
        //len(m)=2, 3 ----> lily
    }
}

func main() {
    m := map[int]string{1: "mike", 2: "yoyo", 3: "lily"}

    DeleteMap(m, 2) //删除key值为2的map

    for k, v := range m {
        fmt.Printf("len(m)=%d, %d ----> %s\n", len(m), k, v)
        //len(m)=2, 1 ----> mike
        //len(m)=2, 3 ----> lily
    }
}

猜你喜欢

转载自blog.csdn.net/weixin_37887248/article/details/83615679