• Golang学习:基础知识篇(三)—— Map(集合)


    Golang学习:基础知识篇(三)—— Map集合

    前言

    很久之前就想学Go语言了,但是一直有其他东西要学,因为我学的是Java嘛,所以后面学的东西一直是跟Java相关的。

    最近来到公司实习,需要用到Go语言,所以就趁着这个机会把Go学了。
    在这里插入图片描述

    什么是Golang?

    简单来说就是由Google公司的Robert Griesemer,Rob Pike和Ken Thompson设计的一种静态类型、编译型语言。它在2009年正式对外公开,目标是解决大规模软件工程中的问题。Go语言的语法简洁清晰,易于学习和使用,编译速度快,具有垃圾回收功能,并且拥有强大的标准库。

    Go语言的主要目标是将静态语言的安全性和高效性与动态语言的易开发性进行有机结合,达到完美平衡,从而使编程变得更加有乐趣,而不是在艰难抉择中痛苦前行。Go语言设计最本质的初衷就是简单,希望程序员的工作量最小化,利用Go本身少量的特性,并通过组合的方式去解决实际问题。

    Map集合

    Map就不用多介绍了吧,跟Java那个是一回事,简单来说就是:

    • Map 是一种无序的键值对的集合。
    • Map 最重要的一点是通过 key 来快速检索数据,key 类似于索引,指向数据的值。
    • Map 是一种集合,所以我们可以像迭代数组和切片那样迭代它。不过,Map 是无序的,遍历 Map 时返回的键值对的顺序是不确定的。
    • 在获取 Map 的值时,如果键不存在,返回该类型的零值,例如 int 类型的零值是 0,string 类型的零值是 “”。
    • Map 是引用类型,如果将一个 Map 传递给一个函数或赋值给另一个变量,它们都指向同一个底层数据结构,因此对 Map的修改会影响到所有引用它的变量。

    (分割线)

    推荐学习教程:菜鸟教程 | Go语言

    我会更侧重讲一些网上教程没有,或者没讲清楚的一些东西。

    定义 Map

    可以使用内建函数 make 或使用 map 关键字来定义 Map:

    /* 使用 make 函数 */
    map_variable := make(map[KeyType]ValueType, initialCapacity)
    
    • 1
    • 2

    其中 KeyType 是键的类型,ValueType 是值的类型,initialCapacity 是可选的参数,用于指定 Map 的初始容量。Map 的容量是指 Map 中可以保存的键值对的数量,当 Map 中的键值对数量达到容量时,Map 会自动扩容。如果不指定 initialCapacity,Go 语言会根据实际情况选择一个合适的值。

    例如:

    // 创建一个空的 Map
    m := make(map[string]int)
    
    // 创建一个初始容量为 10 的 Map
    m := make(map[string]int, 10)
    
    • 1
    • 2
    • 3
    • 4
    • 5

    获取元素:

    // 获取键值对
    v1 := m["apple"]
    v2, ok := m["pear"]  // 如果键不存在,ok 的值为 false,v2 的值为该类型的零值
    
    • 1
    • 2
    • 3

    修改元素:

    // 修改键值对
    m["apple"] = 5
    
    • 1
    • 2

    获取 Map 的长度:

    // 获取 Map 的长度
    len := len(m)
    
    • 1
    • 2

    遍历 Map:

    // 遍历 Map
    for k, v := range m {
        fmt.Printf("key=%s, value=%d\n", k, v)
    }
    
    • 1
    • 2
    • 3
    • 4

    删除元素:

    // 删除键值对
    delete(m, "banana")
    
    • 1
    • 2

    综合实例

    看看菜鸟上面的一个综合实例:

    package main
    
    import "fmt"
    
    func main() {
        var siteMap map[string]string /*创建集合 */
        siteMap = make(map[string]string)
    
        /* map 插入 key - value 对,各个国家对应的首都 */
        siteMap [ "Google" ] = "谷歌"
        siteMap [ "Runoob" ] = "菜鸟教程"
        siteMap [ "Baidu" ] = "百度"
        siteMap [ "Wiki" ] = "维基百科"
    
        /*使用键输出地图值 */ 
        for site := range siteMap {
            fmt.Println(site, "首都是", siteMap [site])
        }
    
        /*查看元素在集合中是否存在 */
        name, ok := siteMap [ "Facebook" ] /*如果确定是真实的,则存在,否则不存在 */
        /*fmt.Println(capital) */
        /*fmt.Println(ok) */
        if (ok) {
            fmt.Println("Facebook 的 站点是", name)
        } else {
            fmt.Println("Facebook 站点不存在")
        }
    }
    
    • 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

    补充

    1、还记得上篇文章提到的那个数组切片吗?就是这个:
    在这里插入图片描述

    但是在Map中,这样子是可以正确赋值的哦,如下:

    func main() {
    
    	myGreeting := make(map[string]string)
    	myGreeting["Tim"] = "Good morning."
    	myGreeting["Jenny"] = "Bonjour."
    
    	fmt.Println(myGreeting)
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    因为在Go语言中,映射是一种动态数据结构,可以在运行时动态地添加和删除键值对。当您创建一个新的映射时,它是空的,但是我们可以立即向其中添加新的键值对。

    然而,切片不同。虽然切片背后的数组可以动态地增长和缩小,但是不能直接访问未初始化的元素。切片中如果你想要向空切片中添加元素,应该使用 append 函数。

    2、还需要注意的地方就是key是区分大小写的哈,记得。

    3、再补充一个if语句和Map的搭配使用

    func main() {
    
    	myGreeting := map[int]string{
    		0: "Good morning!",
    		1: "Bonjour!",
    		2: "Buenos dias!",
    		3: "Bongiorno!",
    	}
    
    	fmt.Println(myGreeting)
    
    	if val, exists := myGreeting[3]; exists {
    		delete(myGreeting, 3)
    		//why can this place still take out the value?
    		//because 这个操作删除了键 3 及其对应的值,但是它并不影响已经被赋值的 val 和
    		//exists 变量。所以,即使你已经从 map 中删除了键 3,当你打印 val 和 exists 的值时,它们仍然保持着初始化时的值。
    		fmt.Println("val: ", val)
    		fmt.Println("exists: ", exists)
    	} else {
    		fmt.Println("That value doesn't exist.")
    		fmt.Println("val: ", val)
    		fmt.Println("exists: ", exists)
    	}
    
    	fmt.Println(myGreeting)
    }
    
    
    • 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

    4、补充一个循环语句遍历Map的例子:

    func main() {
    
    	myGreeting := map[int]string{
    		0: "Good morning!",
    		1: "Bonjour!",
    		2: "Buenos dias!",
    		3: "Bongiorno!",
    	}
    
    	for key, val := range myGreeting {
    		fmt.Println(key, " - ", val)
    	}
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14

    那么以上就是本次的内容了,在学习的过程中,可以多去敲敲代码,熟悉一下。也可以去菜鸟教程上面多看看,对新人挺友好的,也是我的公司同事推荐的教程网站。

    后续也会不定期更新学习记录和一些学习实验。🤠

  • 相关阅读:
    String 为什么不可变?不可变有什么好处?
    Flutter 没有完整的生命周期?
    C# 通过字符串找对应名称的变量、Winform跨容器调用变量、递归遍历XML
    把图片压缩成指定大小,释放你的内存空间
    Git (2)—分支操作
    Go Context 原理详解
    Nginx、MySQL、LNMP安装
    Android混合式开发框架搭建集成Flutter3.0.1
    智慧公厕:打造无人值守的公共厕所运营管理服务
    联想刘军:做深做透全栈AI产品方案和服务,建立差异化竞争优势
  • 原文地址:https://blog.csdn.net/qq_44386537/article/details/133877661