当前位置: 首页 > 科技观察

复合数据类型:字典Mapandstructure

时间:2023-03-16 20:10:24 科技观察

楼下新开了一家重庆砂锅肠,喇叭一直在播放:地道的老重庆砂锅肠,香辣可口,老爷子舒服。我不知道它是不是真的。反正一听口音,我以为又回到了东北。本文介绍上一篇关于复合数据类型:字典和结构的文章。内容很重要,在编程中用的比较多,所以需要掌握。本文所有代码均基于go1.16.6编写。字典字典是一种非常常用的数据结构,在Go中用关键字map表示,类型为map[K]V。K和V分别是字典的键和值的数据类型,其中键必须支持相等运算符,例如数字、字符串等。创建字典有两种方式。第一种是直接创建字典;第二种是使用内置函数make。字面量方法创建://字面量方法创建varm=map[string]int{"a":1,"b":2}fmt.Println(m)//map[a:1b:2]createdusingmake://使用make创建m1:=make(map[string]int)fmt.Println(m1)也初始化了字典的长度。当字典的长度已知时,直接指定长度可以提高程序的执行效率。//指定长度m2:=make(map[string]int,10)fmt.Println(m2)字典的零值为nil,给值为nil的字典赋值时会报错。//零值为nilvarm3map[string]intfmt.Println(m3==nil,len(m3)==0)//truetrue//nil赋值错误//m3["a"]=1//fmt.Println(m3)//panic:assignmenttoentryinnilmap使用字典赋值://assignm["c"]=3m["d"]=4fmt.Println(m)//map[a:1b:2c:3d:4]value://Valuefmt.Println(m["a"],m["d"])//14fmt.Println(m["k"])//0即使Key不存在也没有错.相反,返回相应类型的零值。删除元素://deletedelete(m,"c")delete(m,"f")//key不存在,不会报错fmt.Println(m)//map[a:1b:2d:4]获取长度//获取长度fmt.Println(len(m))//3判断key是否存在://判断key是否存在ifvalue,ok:=m["d"];ok{fmt.Println(value)//4}和Python相比,这个用起来很爽。traverse://遍历fork,v:=rangem{fmt.Println(k,v)}引用类型map是引用类型,所以在函数之间传递时,不会对map进行复制,类似于切片,都非常高效。packagemainimport"fmt"funcmain(){...//传参modify(m)fmt.Println("main:",m)//main:map[a:1b:2d:4e:10]}funcmodify(amap[string]int){a["e"]=10fmt.Println("modify:",a)//modify:map[a:1b:2d:4e:10]}structure该结构是一个聚合类型,包含零个或多个任何类型的命名变量,每个变量称为结构的成员。创建一个结构体,首先使用type定义一个结构体类型user,它有两个成员变量,分别是:name和age。//初始化声明结构体typeuserstruct{namestringageint}结构体有两种方式:第一种是按照声明字段的先后顺序逐个赋值。这里需要注意的是,字段的顺序一定要严格一致。//初始化u1:=user{"zhangsan",18}fmt.Println(u1)//{zhangsan18}这样的缺点很明显。如果顺便改变了字段,那么所有与这个结构体初始化相关的部分都必须跟随Change。所以更推荐使用第二种方式根据字段名进行初始化。//更好的方式//u:=user{//age:20,//}//fmt.Println(u)//{20}u:=user{name:"zhangsan",age:18,}fmt.Println(u)//{zhangsan18}未初始化的字段会被赋值对应类型的零值。使用结构使用点。访问和分配成员变量。//访问结构体成员fmt.Println(u.name,u.age)//zhangsan18u.name="lisi"fmt.Println(u.name,u.age)//lisi18如果结构体的成员变量可用是可比的,那么结构也是可比的。//结构比较u2:=user{age:18,name:"zhangsan",}fmt.Println(u1==u)//falsefmt.Println(u1==u2)//真正的结构嵌套现在我们一个用户结构已经定义好了,假设我们再定义两个结构体admin和leader,如下:懒惰是程序员的必修课。有没有办法重用这两个字段?答案是结构嵌套。使用嵌套的方式优化后,变成了这样:typeadminstruct{uuserisAdminbool}typeleaderstruct{uuserisLeaderbool}代码看起来简单多了。匿名成员但这还不够完美,每次访问嵌套结构的成员变量还是有点麻烦。//结构嵌套a:=admin{u:u,isAdmin:true,}fmt.Println(a)//{{lisi18}true}a.u.name="wangwu"fmt.Println(a.u.name)//wangwufmt.Println(a.u.age)//18fmt.Println(a.isAdmin)//true这时候要求匿名成员出现,不指定名字,只指定类型。这样typeadmin1struct{userisAdminbool}就可以省略中间变量,直接访问我们需要的成员变量。//匿名成员a1:=admin1{user:u,isAdmin:true,}a1.age=20a1.isAdmin=falsefmt.Println(a1)//{{lisi20}false}fmt.Println(a1.name)//lisifmt.Println(a1.age)//20fmt.Println(a1.isAdmin)//false总结本文介绍字典和结构体这两种非常常用的数据类型。虽然篇幅不长,但是基本的操作也都包含了,写代码绝对没有问题。更底层的原理和更灵活的用法需要大家自己去探索和发现。当然,在我写完基础专栏之后,我会分享一些更有深度的文章。欢迎大家关注和交流。至此,数据类型已经介绍完毕。首先,我们学习了基本的数据类型,包括整数、浮点数、复数、布尔值和字符串。然后是复合数据类型,包括数组、切片、字典和结构。这些是围棋的基础知识,必须多加练习才能熟练掌握。本文代码我已经上传到Github,需要的同学可以点击文末地址自行下载。文章中的脑图和源码已经上传到GitHub,需要的同学可以自行下载。本文转载自微信公众号「AlwaysBeta」,可通过以下二维码关注。转载本文请联系AlwaysBeta公众号。