网络工程师的Golang之路 -- Go数据类型(Map、结构体)
发布网友
发布时间:2024-09-17 00:45
我来回答
共1个回答
热心网友
时间:2024-11-16 06:36
版权声明:我已加入“维权骑士”( http://rightknights.com)的版权保护计划,知乎专栏“网路行者”下的所有文章均为我本人(知乎ID:弈心)原创,未经允许不得转载。
如果你喜欢我的文章,请关注我的知乎专栏“网路行者” zhuanlan.hu.com/c_12...
对于Netdevops读者来说,Go中的map大体上可以对应Python中的字典,而结构体(struct)则类似于Python中的类(尽管Go并不是面向对象的语言),首先来看map的应用。
Map重要概念使用Map
下面分别举例讲解如何创建map以及对已有map的键值对增、改、删、查的操作方法。
创建map
在Go中声明map的语法如下:
下面举例创建一个键和值均为字符串类型的map:
这里我们用map[string]string{}创建了一个键和值均为字符串的map,总共有4组键值对,分别用来保存一台交换机的序列号、CPU用量、系统版本以及物理端口数量,然后将其赋值给变量switch1。注意我们同样可以对map使用len()函数来获得map里键值对的数量。
添加键值对
对map添加键值对的方法和Python字典一样,这里我们用switch1["model"] = "C9300"向switch1里添加一组"model": "C9300"的键值对:
这里注意在将新的map打印出来后新添的键值对model:C9300并没有排在map的最后,说明了map是无序的。
修改键值对
对map修改已有键值对的方法和Python字典一样,这里我们使用switch1["CPU"] = "19.0"将键值对"CPU":"25.1"改为"CPU":"19.0":
删除键值对
在Go中我们使用delete()函数来删除map里的键值对,delete()函数里要用到两个参数,第一个是代表map的变量名,第二个是要被删除的键,这里我们使用delete(switch1, "SN")来删除变量switch1里的"SN":"12345abcde"这个键值对:
Nil Map
Map也有零值,其零值为nil,零值map也叫nil map。注意nil map和一个没有任何键值对的空map不是一个概念,我们不能对nil map添加任何键值对,否则程序会崩溃,但是我们可以对空map添加键值对,举例如下:
用make()创建map
除了用来创建切片外,make()也可以用来创建空map(和通过make()只能创建空切片一样,用make()也只能创建空map),举例如下:
这里我们用make()函数创建了一个键和值均为字符串的空map,并将它赋值给变量switch1,随后我们手动为该map添加了"port":"48"和"version":"11.1"两组键值对。
验证指定的键值对是否存在于map中
在map中以variable["key_value"]的形式获取键值时,实际上会返回两个值:一个是键对应的值,一个是布尔值,其中布尔值的作用是用来判断键是否存在,如果存在则返回true,不存在则返回false(键不存在的时候,键对应的值为零值)。我们可以通过双赋值(two-value assignment)的形式来获取这两个值,从而判断我们感兴趣的键是否存在于我们感兴趣的map中,举例如下:
如果你说我只想知道键是否存在于map中,我不关心键对应的值是什么的话,可以用下划线"_"来做变量名,替代变量v,即将v, ok := switch["port"]写成_, ok := switch["port"],举例如下:
在Go语言中,很多函数会返回两个值(类似于Python中字典的items()函数),使用"_"做变量名来屏蔽掉自己不感兴趣的值的方法在双赋值的情况下很常用,后面的章节会多次用到。
结构体重要概念
相信很多学习Go语言到这里的Netdevops读者不禁有一个疑问:Go中的数组、切片、map统统都只能支持统一的数据类型,一个数组或切片里的元素要嘛全部是字符串,要嘛全部是整数、浮点数、布尔值等等,一个map里的键和值也是同样的道理,这点和Python里的列表和字典相比是不是显得太不灵活了?不用担心,Go中的结构体(struct)就能打破这样的*。
前面在 《数组、切片》一章里讲到切片的sliceHeader时我们已经提到了结构体的概念。简单点来说,结构体可以让我们将一组数据集合起来,以便我们能够更加便捷地操作这些数据。每个数据又由字段(field)和其对应的数据类型组成,最重要的是每个字段对应的数据类型相互之间可以完全不一样。除此以外,我们还可以通过结构体根据我们自己的需要来自定义一个全新的数据类型(一个结构体就是一个新的数据类型)。正因如此,在Go中我们使用type这个关键词来定义结构体,举例如下:
这里我们定义了一个叫做router的结构体(也就是创建了一个叫做router的数据类型),该结构体包含Hostname、IP_address、Port、CPU_utilization、Power_on总共五个字段,每个字段又分别对应字符串、整数、64位浮点数、布尔值等数据类型,用来描述一个路由器。
使用结构体
创建了结构体后,接下来我们将它赋值给两个变量router1和router2,看看怎样使用结构体:
这里我们将结构体router“实例化”给了router1和router2。可以看出Go中的结构体和Python的类相似,尽管Go语言本身并不是面向对象的编程语言,但是也能做到类似于Python那样将一个类“实例化”的效果。这里的结构体router就像Python的类一样是一个抽象的模板,而router1和router2就类似于结构体router的实例(instance)。
注意:通常建议将结构体写在main()或者其他自定义函数的外面,这样把结构体放在全局(global)的位置的好处是将来方便它们在同一个Golang包下面被其他的程序调用。不过如果你确认整个包下面只有这一个程序,结构体不会“对外使用”,那将结构体写在main()或者其他自定义函数下面也是可以的。
用new()将结构体赋值给变量
用new()将结构体赋值给变量和用make()创建切片、map一样,我们都不能将结构体字段的初始参数分配给变量,举例如下:
这里注意两点:
接下来我们将router1的各项字段做增添:
下一篇链接: