Go语言容器之map、list和nil

news2024/12/26 11:33:34

一、map

  • map和C++中map一样,里面存放的是key-value键值对
  • 在Go中map是引用类型,声明语法:var map变量名 map[key的类型]value的类型
    package main
    
    import "fmt"
    
    func main() {
    	var mp map[string]int
    	mpls := map[string]int{"one":1, "two":2, "three":3}
    	mpmk := make(map[string]int)
    
    
    	mp = mpls
    	mpmk["语文"] = 1
    	mpmk["数学"] = 2
    	mpmk["英语"] = 4
    	mp["four"] = 4
    	mp["five"] = 5
    
    	fmt.Println("mp[one]", mp["one"])
    	fmt.Println("mp[ten]", mp["ten"])
    	fmt.Println("mp", mp)
    	fmt.Println("mpmk[语文]", mpmk["语文"])
    	fmt.Println(mpmk)
    }
    
    结果:
    在这里插入图片描述

1.map的容量

  • 和数组不一样,map可以根据新增的key-value进行动态的增加删除,所以不存在长度、最大限制;但是可以选择标明map的初始容量capacity,格式如下:
    make(map[key类型]value类型, cap)

2.map的遍历

  • 遍历map可以用for循环语句和range关键字进行遍历
    package main
    
    import "fmt"
    
    func main() {
    	mpls := map[string]int{"one":1, "two":2, "three":3, "four":4, "five":5, "six":6, "seven":7, "eight":8, "nine":9, "ten":10}
    
    	//遍历map
    	for key, value := range mpls{
    		fmt.Printf("key:%s",key)
    		fmt.Printf(": value:%d\n", value)
    		fmt.Println("value:", mpls[key])
    	}
    
    	fmt.Println("只遍历key:")
    	//只遍历key
    	for key, _ := range mpls{
    		fmt.Printf("key:%s ", key)
    	}
    
    	fmt.Println("\n只遍历value:")
    	//只遍历value
    	for _, value := range mpls{
    		fmt.Printf("value:%d ", value)
    	}
    }
    
    结果:
    在这里插入图片描述

3.map中元素的删除

  • delete(map变量名, key对应的键)
    package main
    
    import "fmt"
    
    func main() {
    	mpls := map[string]int{"one":1, "two":2, "three":3, "four":4, "five":5, "six":6, "seven":7, "eight":8, "nine":9, "ten":10}
    
    	//遍历map
    	for key, value := range mpls{
    		fmt.Printf(" key: %s, value: %d||",key, value)
    	}
    
    	delete(mpls, "five")
    	delete(mpls,"nine")
    	delete(mpls,"three")
    	fmt.Println("\n删除后:")
    	fmt.Println(mpls)
    }
    
    结果:在这里插入图片描述

4.并发map(sync.Map)

  • Go语言中,map在并发情况下,只读是线程安全的,但是同时读写线程是不安全的
  • 需要并发读写的时候,一般是用加锁的方式。go中有一个效率高的并发安全的map,即snyc.Map。
  • sync.Map有以下特征:
    (1)无须初始化,直接声明即可
    (2)sync.Map和map不一样,不可以用map的方式对其进行操作。而是有自己特有的方式,Store表示存储,Load表示获取,Delete表示删除
    (3)使用Range配合一个回调函数进行遍历错做,通过回调函数返回内部遍历出来的值,Range参数中回调函数的返回值在需要继续迭代遍历时,返回true,终止遍历时返回false
  • 举例:
    package main
    
    import (
    	"fmt"
    	"sync"
    )
    
    func main() {
    	var snmp sync.Map
    
    	//存储数据
    	snmp.Store("语文", 100)
    	snmp.Store("数学", 130)
    	snmp.Store("英语", 120)
    	snmp.Store("生物", 90)
    	snmp.Store("物理", 30)
    
    	//查看数据
    	fmt.Println(snmp.Load("生物"))
    	fmt.Println(snmp.Load("数学"))
    
    	//删除数据
    	snmp.Delete("生物")
    
    	//遍历
    	snmp.Range(func(k, v interface{})bool{
    		fmt.Println("iterate:", k, v)
    		return true
    	})
    }
    
    结果:
    在这里插入图片描述

二、list

  • 在Go中,列表list内部的实现原理是双链表,能够高效地进行任意位置元素的插入和删除操作

1.列表的初始化

  • 方式一:通过container/list包中的New()函数来进行初始化。变量名 := list.New()
  • 方式二:通过var关键字声明初始化list。var 变量名 list.List

2.列表的插入、删除

  • 向列表中插入元素,因为是双链表,可以从队尾、队首两头直接插。PushFront向队首前方插入元素,PushBack向队尾后方插入元素,InsertAfter在队列中某元素之后插入一个元素,InsertBefore在队列某元素之前插入一个元素
  • Remove移除某个元素
package main

import (
	"container/list"
	"fmt"
)

func main() {
	ls := list.New()
	ls.PushFront("d")//队首添加d
	ele2 := ls.PushBack("e")//队尾添加e。且存放e元素的句柄。队列:d->e
	ele1 := ls.PushFront("c")//队首添加c。且存放c元素的句柄。队列:c->d->e
	ls.PushBack("g")//队尾添加f。队列:c->d->e->g
	ls.PushFront("a")//队首添加a。队列:a->c->d->e->g

	//遍历队列:
	for i := ls.Front(); i != nil; i = i.Next(){
		fmt.Printf(" %v -> ", i.Value)
	}
	fmt.Println()

	ls.InsertBefore("b", ele1)//在c元素前面添加b。队列:a->b->c->d->e->g
	ls.InsertAfter("f", ele2)//在e元素后面添加f。队列:a->b->c->d->e->f->g
	ele3 := ls.InsertAfter("i", ele2)//在e元素后面添加i。队列:a->b->c->d->e->i->f->g
	//遍历队列:
	for i := ls.Front(); i != nil; i = i.Next(){
		fmt.Printf(" %v -> ", i.Value)
	}

	ls.Remove(ele3)//删除元素i
	fmt.Println()
	//遍历队列:
	for i := ls.Front(); i != nil; i = i.Next(){
		fmt.Printf(" %v -> ", i.Value)
	}
}

结果:
在这里插入图片描述

三、零值、空值nil

  • 在Go语言中,布尔类型的零值(初始化值)为false,数值类型的零值为0,字符串类型的零值为空字符串"",而指针、切片、映射、通道和接口类型的零值都是nil空值
  • Go中,nil是一个预定义好的标识符。

1.nil的特性

(1)nil是不能比较的,无论nil的类型是否相同也都不能进行比较,会编译报错

package main

import "fmt"

func main() {
	fmt.Println(nil == nil)
}

结果:在这里插入图片描述(2)nil不是关键字或者保留字
(3)nil没有默认的类型
(4)不同类型的nil的指针是一样的

package main

import (
	"fmt"
)

func main() {
	var arr[]int
	var mp map[int]int
	var num int

	fmt.Printf("%p\n", arr)
	fmt.Printf("%p\n", mp)
	fmt.Printf("%p\n", num)
}

结果:
在这里插入图片描述
(5)nil是指针、切片、map、channel、接口、函数的零值

package main

import (
	"fmt"
)

func main() {
	var ptr *string
	var slce []int
	var arr[]int
	var mp map[int]int
	var cha chan int
	var fn func()
	var ins interface{}

	fmt.Printf("%#v\n", ptr)
	fmt.Printf("%#v\n", slce)
	fmt.Printf("%#v\n", arr)
	fmt.Printf("%#v\n", mp)
	fmt.Printf("%#v\n", cha)
	fmt.Printf("%#v\n", fn)
	fmt.Printf("%#v\n", ins)
}

结果:
在这里插入图片描述
(6)不同类型的nil值占用的内存大小不一样,按照类型大小

package main

import (
	"fmt"
	"unsafe"
)

func main() {
	var ptr *string
	var slce []int
	var arr[]int
	var mp map[int]int
	var cha chan int
	var fn func()
	var ins interface{}

	fmt.Println(unsafe.Sizeof(ptr))
	fmt.Println(unsafe.Sizeof(slce))
	fmt.Println(unsafe.Sizeof(arr))
	fmt.Println(unsafe.Sizeof(mp))
	fmt.Println(unsafe.Sizeof(cha))
	fmt.Println(unsafe.Sizeof(fn))
	fmt.Println(unsafe.Sizeof(ins))
}

结果:
在这里插入图片描述

四、make和new关键字的区别

  • 两个内置函数可以用来在堆上分配内存
  • make只能用来分配和初始化slice、map、chan的类型的数据,而new可以分配任意类型的数据
  • make分配数据内存返回的是引用,即Type,而new返回一个指向接收参数类型的指针,即*Type。(make 关键字的主要作用是创建 slice、map 和 Channel 等内置的数据结构,而 new 的主要作用是为类型申请一片内存空间,并返回指向这片内存的指针。
  • 接收参数个数不一样:make() 只接收一个参数,而 new() 可以接收多个参数
  • make分配的空间后,会进行初始化。而new分配的空间会清零

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/401818.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

不用写代码也能开发,产品经理是怎么做到的?

产品经理再也不用求开发了……就在前几天,我做的小程序上线了! 从产品原型设计,前端开发后端开发,产品部署到运维,都是由我1个人完成的。 我是啥时候学会写代码的呢?不瞒你说,我一行代码都没写…

基于卷积神经网络CNN的甘蔗芽体自动识别,卷积神经网络分类预测

目录 背影 卷积神经网络CNN的原理 卷积神经网络CNN的定义 卷积神经网络CNN的神经元 卷积神经网络CNN的激活函数 卷积神经网络CNN的传递函数 卷积神经网络CNN甘蔗芽体自动识别 基本结构 主要参数 MATALB代码 结果图 展望 背影 现在生活,为节能减排,减少…

LauterBach使用教程

工作需要,使用到劳得巴赫,但是公司只买了调试器,却没有买教程,所以就只能自己摸索和网上搜索这两种途径来学习。 注意:lauterbach可以使用命令来操作,但是由于本人刚刚使用,目前基本上使用的都…

[考前冲刺]计算机三级网络技术复习知识点总结·计算机三级网络技术重难点考前冲刺和解题技巧

选择题第一章重难点一、网络层次结构的功能①核心交换层的基本功能:1、核心交换层将多个汇聚层连接起来,为汇聚层的网络提供高速转发,为整个城域网提供一个高速、安全与具有QoS保障能力的数据传输环境;2、核心交换层实现与主干网络…

2023最新版会声会影更新下载及功能介绍

会声会影(Corel VideoStudio)为加拿大Corel发布的一款功能丰富的视频编辑软件。会声会影2023简单易用,具有史无前例的强大功能,拖放式标题、转场、覆叠和滤镜,色彩分级、动态分屏视频和新增强的遮罩创建器,…

Nuxt项目配置、目录结构说明-实战教程基础-Day02

Nuxt项目配置、目录结构说明-实战教程基础-Day02一、Nuxt项目结构1.1资源目录1.2 组件目录1.3 布局目录1.4 中间件目录1.5 页面目录1.6 插件目录1.7 静态文件目录1.8 Store 目录1.9 nuxt.config.js 文件1.10 package.json 文件其他:别名二、项目配置2.1 build2.2 cs…

0108检测环-无向图-数据结构和算法(Java)

文章目录1 API2 实现和分析3 测试后记1 API 检测一幅图是否还有环&#xff0c;如果有找出环路&#xff08;任意一条&#xff09;&#xff0c;API如下&#xff1a; public classCycleCycle(Grpah G)预处理函数booleanhasCycle()Iterable<Interge>cycle()有环给出环路&am…

用友开发者中心应用构建实践指引!

基于 iuap 技术底座&#xff0c;用友开发者中心致力于为企业和开发者提供一站式技术服务&#xff0c;让人人都能轻松构建企业级应用。 本文以人力资源领域常用的应聘人员信息登记与分析功能为例&#xff0c;详细介绍如何在用友开发者中心使用 YonBuilder 进行应用构建。 功能…

计算机操作系统--哈工大(2)

操作系统的那棵树 本来看着网课是20个小时&#xff0c;还自以为是想着几周学完&#xff0c;是我太自大了&#xff0c;被现实狠狠殴打CPU调度策略如何让进程满意总原则&#xff1a;系统专注于任务执行又能合理调配任务前台任务关注响应时间&#xff0c;后台任务关注周转时间各种…

【C++】C++11新特性——右值引用

文章目录一、左值引用、 右值引用1.1 左值与右值1.2 左值引用1.3 右值引用二、右值引用的意义三、移动语句3.1 移动构造3.2 移动赋值3.3 总结四、move问题五、完美转发5.1 万能引用与折叠5.2 完美转发std::forward一、左值引用、 右值引用 1.1 左值与右值 我们经常能听到左值…

服务搭建篇(九) 使用GitLab+Jenkins搭建CI\CD执行环境 (上) 基础环境搭建

1.前言 每当我们程序员开发在本地完成开发之后 , 都要部署到正式环境去使用 , 在一些传统的运维体系中 , 开发与运维都是割裂的 , 开发人员不允许操作正式服务器 , 服务器只能通过运维团队来操作 , 这样可以极大的提高服务器的安全性 , 不经过安全保护的开放服务器 , 对于黑客…

6、DDIM

简介 去噪扩散概率模型(DDPM)在没有对抗性训练的情况下已经实现了高质量的图像生成&#xff0c;但它们需要模拟马尔可夫链许多步骤才能生成样本。 例如&#xff0c;从DDPM采样50k张大小为32 32的图像需要大约20个小时&#xff0c;而从Nvidia 2080 Ti GPU上的GAN采样则需要不…

Vue:(三十五)路由vue-router

今天&#xff0c;我们开始学习vue中一个很关键的知识点&#xff0c;路由。理解vue的一个插件库&#xff0c;专门用来实现SPA应用单页web应用整个应用只有一个完整的页面点击页面中的导航连接不会刷新页面&#xff0c;只会做页面的局部更新数据需要通过ajax请求获取下来&#xf…

css制作动画(动效的序列帧图)

相信 animation 大家都用过很多&#xff0c;知道是 CSS3做动画用的。而我自己就只会在 X/Y轴 上做位移旋转&#xff0c;使用 animation-timing-function 规定动画的速度曲线&#xff0c;常用到的 贝塞尔曲线。但是这些动画效果都是连续性的。 今天发现个新功能 animation-timi…

【C语言】详讲qsort库函数

qsort函数介绍具体作用qsort函数是一种用于对不同类型数据进行快速排序的函数&#xff0c;排序算法有很多最常用的冒泡排序法仅仅只能对整形进行排序,qsort不同,排序类型不受限制,qsort函数的底层原理是一种快速排序.基本构造qsort( void* arr, int sz, int sizeof, cmp_code);…

【毕业设计】基于Java的五子棋游戏的设计(源代码+论文)

简介 五子棋作为一个棋类竞技运动&#xff0c;在民间十分流行&#xff0c;为了熟悉五子棋规则及技巧&#xff0c;以及研究简单的人工智能&#xff0c;决定用Java开发五子棋游戏。主要完成了人机对战和玩家之间联网对战2个功能。网络连接部分为Socket编程应用&#xff0c;客户端…

IP协议+以太网协议

在计算机网络体系结构的五层协议中&#xff0c;第三层就是负责建立网络连接&#xff0c;同时为上层提供服务的一层&#xff0c;网络层协议主要负责两件事&#xff1a;即地址管理和路由选择&#xff0c;下面就网络层的重点协议做简单介绍~~ IP协议 网际协议IP是TCP/IP体系中两…

20230310英语学习

Some Narcissists Chase Status, Others Want to Win Admiration 自恋并非自尊心膨胀&#xff0c;那它因何而来&#xff1f; Narcissists often rub their friends and family the wrong way by bragging about their exploits, seemingly a symptom of an overinflated sense …

什么是AIGC?

目录前言一、什么是AIGC&#xff1f;1、什么是PGC&#xff1f;2、什么是UGC&#xff1f;3、什么是PUCG&#xff1f;4、什么是AIGC&#xff1f;二、总结前言 很明显&#xff0c;ChatGPT的爆火&#xff0c;带动了AIGC&#xff08;AI-Generated Content&#xff09;概念的火热。 …

DP算法:动态规划算法

步骤&#xff08;1&#xff09;确定初始状态&#xff08;2&#xff09;确定转移矩阵&#xff0c;得到每个阶段的状态&#xff0c;由上一阶段推到出来&#xff08;3&#xff09;确定边界条件。例题蓝桥杯——印章&#xff08;python实现&#xff09;使用dp记录状态&#xff0c;d…