Golang语言之映射(map)快速入门篇

简介: 这篇文章是关于Go语言中映射(map)的快速入门教程,涵盖了map的定义、创建方式、基本操作如增删改查、遍历、嵌套map的使用以及相关练习题。

                                              作者:尹正杰
版权声明:原创作品,谢绝转载!否则将追究法律责任。

一.映射(map)定义

1.映射(map)概述

映射(map)是一种无序的基于key-value的数据结构,Go语言中的map是引用类型,必须初始化才能使用。

Go语言中提供的映射关系容器为map,其内部使用散列表(hash)实现。

映射(map)是Go语言中内置的一种类型,它将键值相关联,我们可以通过key来获取对应的value,有点类似于其他语言的集合。

映射(map)的特点:
    - 1.map结合在使用前一定要make;
    - 2.map的key-value是无序的;
    - 3.key是不可以重复的,如果遇到重复,后一个value会替换前一个value;
    - 4.不同的key,其value是可以重复的;

2.map的语法格式

Go语言中map的定义语法如下:
    map[KeyType]ValueType

map类型的变量默认初始值为nil,需要使用make()函数来分配内存。语法为:
    make(map[KeyType]ValueType, [cap])

    相关字段说明:
    KeyType:
      表示键的类型。
    ValueType:
      表示键对应的值的类型。
    cap
      map的容量,该参数可选,但建议在初始化map的时候就为其指定一个合适的容量。

温馨提示:
    - 1.key,value的类型包括但不限于bool,数值型,string,指针,chan,还可以只包含前面几个类型的接口,结构体,数组等;
    - 2.key部分通常为int,string类型,value通常为数字(整数,浮点数),string,map,结构体;
    - 3.key部分不可以是slice,map,function等类型;

3.map的三种创建方式

3.1 先声明在make

package main

import "fmt"

func main() {

    // 1.声明map变量,但并没有分配堆内存空间
    var dongMan map[int]string

    // 2.必须通过make函数进行初始化,才会在堆内存中分配空间
    dongMan = make(map[int]string, 5) // map可以存放5个键值对,但实际存储超过5个依旧是可以的

    // 3.将键值对存储map中
    dongMan[20230925] = "《仙逆》"
    dongMan[20200725] = "《凡人修仙传》"
    dongMan[20201129] = "《吞噬星空》"
    dongMan[20220129] = "《永生》"
    dongMan[20140731] = "《画江湖之不良人》"
    dongMan[20131214] = "《师兄啊师兄》"
    dongMan[20021003] = "《火影忍者》"
    dongMan[20080517] = "《葫芦兄弟》"
    dongMan[19990723] = "《西游记》"

    // 4.输出集合
    fmt.Printf("dongman = %v\n", dongMan)
}

3.2 直接使用make初始化map

package main

import "fmt"

func main() {

    // 1.初始化map类型
    language := make(map[string]uint16)

    // 2.赋值
    language["C"] = 1972
    language["C++"] = 1983
    language["Python"] = 1989
    language["JAVA"] = 1995
    language["Golang"] = 2007
    language["Scala"] = 2003
    language["Ruby"] = 1993
    language["Php"] = 2004
    language["HTML"] = 1989
    language["CSS"] = 1994
    language["JavaScript"] = 1995

    // 3.查看map数据
    fmt.Printf("language = [%v]\n", language)
}

3.3 直接赋值初始化map

package main

import "fmt"

func main() {

    dbInfo := map[string]string{
        "Username": "jasonyin2020",
        "Password": "yinzhengjie",
        "DbHost":   "www.yinzhengjie.com",
        "DbPort":   "3306",
        "DbName":   "wordpress",
    }

    fmt.Printf("userInfo = %v\n", dbInfo)
}

二.map基本使用

1.map的增删改查

package main

import "fmt"

func main() {
    // 1.定义map
    constellation := make(map[string]string)

    // 2.增加
    constellation["金牛座"] = "土象星座: 0420-0520"
    constellation["处女座"] = "土象星座: 0823-0922"
    constellation["摩羯座"] = "土象星座: 1222-0119"

    // 3.修改
    constellation["狮子座"] = "火象星座: 0723-0822"

    fmt.Printf("删除前: len(constellation) = %d\n", len(constellation))

    // 4.删除指定map的key,若key不存在,并不会报错
    delete(constellation, "摩羯座")
    fmt.Printf("删除后: len(constellation) = %d\n", len(constellation))

    // 5.查找,判断某个键是否存在
    value, ok := constellation["狮子座"]
    if ok {
        fmt.Printf("狮子座的出生日期: %v\n", value)
    } else {
        fmt.Println("查无此人")
    }

    fmt.Printf("星座: %v\n", constellation)

}

2.map的遍历

package main

import "fmt"

func main() {
    constellation := make(map[string]string)

    constellation["金牛座"] = "土象星座: 0420-0520"
    constellation["处女座"] = "土象星座: 0823-0922"
    constellation["摩羯座"] = "土象星座: 1222-0119"
    constellation["狮子座"] = "火象星座: 0723-0822"

    // Go语言中使用for range遍历map,遍历map时的元素顺序与添加键值对的顺序无关。
    for key, value := range constellation {
        fmt.Printf("key = %v, value = %v\n", key, value)
    }

    fmt.Println("----- 我是分割线 -----")

    // 但我们只想遍历key的时候,仅需使用一个参数来接收哟~
    for k := range constellation {
        fmt.Printf("key = %v\n", k)
    }

}

3.嵌套map遍历

package main

import "fmt"

func main() {

    dongMan := make(map[string]map[int]string)

    // 由于map的值为map类型,因此我们需要对值先进行make再使用,否则会抛出异常
    dongMan["腾讯视频"] = make(map[int]string, 3)
    dongMan["腾讯视频"][20230925] = "《仙逆》"
    dongMan["腾讯视频"][20201129] = "《吞噬星空》"
    dongMan["腾讯视频"][20140731] = "《画江湖之不良人》"

    // 由于map的值为map类型,因此我们需要对值先进行make再使用,否则会抛出异常
    dongMan["B站"] = make(map[int]string, 2)
    dongMan["B站"][20200725] = "《凡人修仙传》"
    dongMan["B站"][20220129] = "《永生》"

    // 由于map的值为map类型,因此我们需要对值先进行make再使用,否则会抛出异常
    dongMan["优酷"] = make(map[int]string, 2)
    dongMan["优酷"][20131214] = "《师兄啊师兄》"
    dongMan["优酷"][20021003] = "《火影忍者》"

    for k1, v1 := range dongMan {
        fmt.Printf("k1 = %v\n", k1)

        for k2, v2 := range v1 {
            fmt.Printf("[%v]动漫的发行时间是: [%d]\n", v2, k2)
        }
    }
}

4.元素为map类型的切片

package main

import (
    "fmt"
)

func main() {
    // 定义一个长度为3的切片
    var mapSlice = make([]map[string]string, 3)

    // 对切片的各个元素进行遍历
    for index, value := range mapSlice {
        fmt.Printf("index: %d value: %v\n", index, value)
    }

    fmt.Println("----- 分割线 -----")

    // 对切片中的第一个(索引下标为0)map元素进行初始化
    mapSlice[0] = make(map[string]string, 10)
    mapSlice[0]["name"] = "Jason Yin"
    mapSlice[0]["password"] = "123456"
    mapSlice[0]["address"] = "北京市昌平区沙河镇"

    for index, value := range mapSlice {
        fmt.Printf("index: %d value: %v\n", index, value)
    }
}

5.值为切片类型的map

package main

import (
    "fmt"
)

func main() {
    // 定义一个map类型
    var sliceMap = make(map[string][]string, 3)

    key := "中国"
    value, ok := sliceMap[key]
    if !ok {
        // 如果key="中国"不存在,则对其值进行初始化为一个容量为2的字符串切片。
        value = make([]string, 0, 2)
    }

    // 紧接着,由于切片是引用类型,我们往该切片中添加2个字符串类型元素
    value = append(value, "北京", "上海")

    fmt.Printf("地址: %p, 数据: %v, 长度: %d, 容量: %d\n", value, value, len(value), cap(value))

    // 往切片追加元素,原有的切片底层数组将存不下,于是会产生新的底层数组哟~
    value = append(value, "深圳", "石家庄", "西安")
    fmt.Printf("地址: %p, 数据: %v, 长度: %d, 容量: %d\n", value, value, len(value), cap(value))

    // 注意,此处我们切片进行赋值给map的key。
    sliceMap[key] = value
    fmt.Println(sliceMap)
}

三.练习题

1.写一个程序,统计一个字符串中每个单词出现的次数

package main

import (
    "fmt"
    "strings"
)

func main() {

    // 统计一个字符串中每个单词出现的次数
    s1 := "I love you , and you ?"

    // 将字符串按照空格子串进行切割
    res := strings.Split(s1, " ")

    // 初始化用于单词统计的map
    var wordCount = make(map[string]int, 10)

    // 如果单词不存在,则将其值设置为1,若存在,则将其值进行加一操作。
    for _, value := range res {
        _, ok := wordCount[value]
        if !ok {
            wordCount[value] = 1
        } else {
            wordCount[value]++
        }
    }

    // 遍历字典
    for k, v := range wordCount {
        fmt.Printf("%s: %d\n", k, v)
    }

}

2.看代码手写结果

package main

import (
    "fmt"
)

func main() {
    // 自定义一个Map类型,底层对应的是一个map类型哟~
    type Map map[string][]int

    // 初始化咱们的自定义类型
    m := make(Map)
    s1 := []int{100, 200}
    s1 = append(s1, 300)
    fmt.Printf("s1 = %+v\n", s1)

    m["JasonYin"] = s1
    s1 = append(s1[:1], s1[2:]...)
    fmt.Printf("s1 = %+v\n", s1)
    fmt.Printf("m['JasonYn'] = %+v\n", m["JasonYin"])
}
目录
相关文章
|
24天前
|
Go
go语言中遍历映射(map)
go语言中遍历映射(map)
42 8
|
3月前
|
Go
Golang语言之gRPC程序设计示例
这篇文章是关于Golang语言使用gRPC进行程序设计的详细教程,涵盖了RPC协议的介绍、gRPC环境的搭建、Protocol Buffers的使用、gRPC服务的编写和通信示例。
112 3
Golang语言之gRPC程序设计示例
|
16天前
|
Go
go语言for遍历映射(map)
go语言for遍历映射(map)
29 12
|
20天前
|
存储 Go
go语言 遍历映射(map)
go语言 遍历映射(map)
32 2
|
3月前
|
Prometheus Cloud Native Go
Golang语言之Prometheus的日志模块使用案例
这篇文章是关于如何在Golang语言项目中使用Prometheus的日志模块的案例,包括源代码编写、编译和测试步骤。
71 3
Golang语言之Prometheus的日志模块使用案例
|
3月前
|
Go 定位技术 索引
Go 语言Map(集合) | 19
Go 语言Map(集合) | 19
|
2月前
|
前端开发 中间件 Go
实践Golang语言N层应用架构
【10月更文挑战第2天】本文介绍了如何在Go语言中使用Gin框架实现N层体系结构,借鉴了J2EE平台的多层分布式应用程序模型。文章首先概述了N层体系结构的基本概念,接着详细列出了Go语言中对应的构件名称,包括前端框架(如Vue.js、React)、Gin的处理函数和中间件、依赖注入和配置管理、会话管理和ORM库(如gorm或ent)。最后,提供了具体的代码示例,展示了如何实现HTTP请求处理、会话管理和数据库操作。
37 0
|
3月前
|
存储 前端开发 API
ES6的Set和Map你都知道吗?一文了解集合和字典在前端中的应用
该文章详细介绍了ES6中Set和Map数据结构的特性和使用方法,并探讨了它们在前端开发中的具体应用,包括如何利用这些数据结构来解决常见的编程问题。
ES6的Set和Map你都知道吗?一文了解集合和字典在前端中的应用
|
4月前
|
存储 安全 Java
java集合框架复习----(4)Map、List、set
这篇文章是Java集合框架的复习总结,重点介绍了Map集合的特点和HashMap的使用,以及Collections工具类的使用示例,同时回顾了List、Set和Map集合的概念和特点,以及Collection工具类的作用。
java集合框架复习----(4)Map、List、set
|
4月前
|
Java
【Java集合类面试二十二】、Map和Set有什么区别?
该CSDN博客文章讨论了Map和Set的区别,但提供的内容摘要并未直接解释这两种集合类型的差异。通常,Map是一种键值对集合,提供通过键快速检索值的能力,而Set是一个不允许重复元素的集合。