网络工程师的Golang之路Go数据类型(接口)
版权声明:我已加入"维权骑士"(http://rightknights.com)的版权保护计划,知乎专栏"网路行者"下的所有文章均为我本人(知乎ID:弈心)原创,未经允许不得转载。
如果你喜欢我的文章,请关注我的知乎专栏"网路行者"https://zhuanlan.zhihu.com/c_126268929, 里面有更多像本文一样深度讲解计算机网络技术的优质文章。接口基本概念
前面在讲解结构体的时候提到了:结构体允许我们自定义一个新的数据类型。在Go语言中,接口(Interfaces)和结构体一样,都属于自定义类型(User-defined Type)。
接口用来定义一个或多个方法签名(method signatures),换句话说,接口是方法的集合。重点:接口本身只声明方法及其返回的值的类型,并不会定义该方法的实施细节(implementation details),也就是说接口不会告诉我们这个方法具体做了些什么,因此接口是抽象的(Go语言中唯一一种抽象类型)。正因如此,不同于结构体,我们不能创建接口的实例,但是可以创建类型为接口的变量。创建接口type demo_interface interface{ demo_method1() int //接口声明的第一种方法 demo_method2() float64 //接口声明的第二种方法 }
这里我们创建了一个叫做demo_interface的接口,该接口定义了demo_method1()和demo_method2()两种方法。 demo_method1()和demo_method2()在接口里又被叫做方法签名。实现接口
前面讲了,接口本身只定义方法及其返回的值的类型,并不会定义该方法的实施细节(implementation details),也就是说接口不会告诉我们这个方法具体做了些什么。
和其他语言不同,Go中的接口是隐式实现的,Go语言中没有直接用来实现接口的关键词。为了实现接口,我们还必须额外创建自定义方法来实现接口里声明的所有方法,注意必须是实现接口里声明的所有方法,上面我们创建的demo_interface这个接口里定义了demo_method1()和demo_method2()两个方法,我们必须将它们都实现了才能实现接口,缺一不可。
下面通过两个例子来说明如何实现接口。简单例子package main import "fmt" //声明一个叫做demo_interface的接口,该接口里声明了一个叫做demo_method()的方法(或方法签名) //该demo_method()方法返回值的数据类型为字符串 type demo_interface interface { demo_method() string } //声明一个叫做demo_type的类型(结构体),该类型(结构体)里包含一个叫做demo_field的字段 //demo_field字段返回值的数据类型为字符串 type demo_type struct { demo_field string } //为demo_type类型创建一个方法 //该方法使用了demo_interface接口里声明的demo_method(),并且其返回值也为字符串 //因此该方法实现了demo_interface接口里声明的demo_method()方法(或方法签名) //因此demo_type类型"隐式地"实现了demo_interface接口 func (instance demo_type) demo_method()string{ return instance.demo_field } //将demo_type类型(结构体)实例化给变量demo_instance,并为其demo_field字段赋值"hello world!" //最后打印出demo_instance变量 func main() { demo_instance := demo_type{"hello, world!"} fmt.Println(demo_instance) }
网络运维例子
看了上面的简单例子后,作为网络工程师的你可能理解了如何在Go语言中实现接口,但还是不知道它能在网络工程师的日常运维自动化中起到什么样的作用,下面来举个例子说明。
假设有一个需求,我们需要通过Go脚本分别从思科的IOS交换机和NX-OS路由器里获取它们的系统uptime,然后比较:IOS和IOS设备之间的uptime,看哪台设备的uptime时间更久。NX-OS和NX-OS设备之间的uptime,看哪台设备的uptime时间更久。IOS和NX-OS设备之间的uptime,看哪台设备的uptime时间更久。
为了实现这个需求,首先我们创建一个叫做IOS的结构体类型,该结构体里包含Hostname和Platform两个字段用来描述所有IOS交换机都有的主机名和设备型号,然后我们为该结构体创建一个叫做getUptime()的方法用来获取所有IOS交换机的uptime,最后我们创建一个叫做compare_ios_uptime()的自定义函数用来比较两台设备谁的uptime时间更久。
实现上述需求的代码如下。//创建一个叫做IOS的类型(结构体)用来描述所有思科IOS交换机 //该IOS类型(结构体)包含Hostname和Platform两个类型为字符串的字段 type IOS struct { Hostname string Platform string } //为IOS结构体类型创建一个叫做getUptime()的方法用来获取IOS交换机的uptime //该方法返回值的类型为整数,方法具体的实现过程不再本篇讨论范围内 func (ios_sw IOS) getUptime() int { /* 具体实现过程略去 */ } //创建一个叫做CompareIosUptime()的函数,用来比较两台IOS交换机谁的uptime更长 func CompareIosUptime(ios_sw1 IOS, ios_sw2 IOS) bool { return ios_sw1.getUptime() < ios_sw2.getUptime() }
同样的道理,我们创建一个叫做NX_OS的结构体类型来描述所有的NX-OS路由器,区别在于:因为此时有其它的需求,除了Hostname和Platform字段外,NX_OS结构体里还额外多了一个叫做ACI的字段(布尔类型),用来判断和描述某个NX-OS路由器里是否开启了ACI模式。
除此之外,我们也会为NX_OS类型创建一个叫做getUptime()的方法和CompareNxosUptime()函数来分别获取NX-OS路由器的uptime,以及比较两台NX-OS路由器之间的uptime,看哪边的uptime时间更久,这点和IOS交换机里的getUptime()的方法和CompareIosUptime函数完全一样。
实现上述需求的代码如下。//创建一个叫做NX_OS的类型(结构体)用来描述所有思科NX-OS路由器 //该NX_OS类型(结构体)包含Hostname、Platform和ACI三个字段 type NX_OS struct { Hostname string Platform string ACI bool } //为NX_OS结构体类型创建一个叫做getUptime()的方法用来获取NX-OS路由器的uptime //该方法返回值的类型为整数,方法具体的实现过程不再本篇讨论范围内 func (nxos_rt NX_OS) getUptime() int { /* 具体实现过程略去 */ } //创建一个叫做CompareNxosUptime()的函数,用来比较两台NX-OS路由器谁的uptime更长 func CompareNxosUptime(nxos_rt1 NX_OS, nxos_rt2 NX_OS) bool { return nxos_rt1.getUptime() < nxos_rt2.getUptime() }
至此,前面提到的三个需求我们已经实现了前两个:比较IOS和IOS设备之间的uptime,看哪台设备的uptime时间更久。(需求已实现)比较NX-OS和NX-OS设备之间的uptime,看哪台设备的uptime时间更久。(需求已实现)比较IOS和NX-OS设备之间的uptime,看哪台设备的uptime时间更久。
目前再来看最后一个需求,其难度在于:因为我们创建的IOS结构体类型和NX_OS结构体类型属于不同的两种类型(后者有ACI字段,前者没有),因此我们无法简单地创建一个函数来比较它们的uptime。
为了解决这个问题,我们可以创建一个叫做CiscoDevice的接口,在该接口里声明一个叫做getUptime()的方法,该方法返回值的类型为整数,因为IOS结构体类型和NX_OS结构体类型都有一个叫做getUptime()的方法,且同样返回整数,因此IOS结构体类型和NX_OS结构体类型都"隐式地"实现了该CiscoDevice的接口,接口代码如下。type CiscoDevice interface { getUptime() int }
通过创建这个接口,我们巧妙地让本来不属于同一类型的IOS类型和NX_OS类型此时同属于CiscoDevice这个接口类型,随后我们再创建一个叫做CompareIosNxosUptime()的函数,该函数里需要两个参数来分别代表IOS交换机和NX-OS路由器,两个参数的数据类型均为CiscoDevice(接口类型),然后就可以顺利地比较它们的uptime了,代码如下。func CompareIosNxosUptime(device1 CiscoDevice, device2 CiscoDevice) bool { return device1.getUptime() < device2.getUptime() } func main() { ios := IOS{} nxos := NX_OS{} if CompareIosNxosUptime(ios, nxos) { fmt.Println("IOS交换机uptime时长比NX-OS路由器短") os.Exit(0) } }
早酒对身体有益还是有害,精英白领为什么不喝早酒早酒文化是中国传统文化的一部分,喝酒在中国社会中有着悠久的历史。在早餐时喝酒,被称为早酒,一些人认为这种做法可以促进消化增加食欲,还可以提高精神状态。然而,对于早酒对身体的影响,人
45岁周韵真不愧是穿衣高手,各种裙装打扮洋气又高级,照着穿准美有一种胜过时间的美,叫东方风骨有一种中年,叫做周韵的45岁。看了周韵,才明白什么是真正的美人在骨不在皮不少人对周韵的印象还停留在邪不压正中素雅美丽的关巧红上。事实上,周韵日常的穿衣
纽约时装周爆丑闻,模特儿演出被诱骗无偿工作25岁模特儿斯图尔特(TaylorStewart)在社交网大爆时装界黑暗面,指很多模特儿发型师化妆师在纽约时装周受尽剥削,被诱骗无偿工作,她自己曾演出7场时装表演都不获分文工资。纽
纵然随风起舞,也要落叶归根收头发,收长头发。换菜刀。换盆饭碗收手机。收报废手机。叫醒我的。不是清晨的第一缕阳光。也不是清脆的鸟鸣。是勤奋的收头发小贩。这样走街串巷的小贩在北上广深那种大城市。应该很少见。但在
聪明人不会在朋友面前说这4句话,蠢人却挂在嘴边,难怪人缘差!图源自网络侵权请联系删除一个人的情商高低,其实并不是天生的,而是在后天的环境里慢慢养成的。当你懂得谨言慎行,懂得为他人着想,懂得对自己的言行负责,那么慢慢地,你就会变成一个被人尊重
我们穷极一生,追求的到底是什么?王羲之说夫人之相与,俯仰一世,或取诸怀抱,悟言一室之内或因寄所托,放浪形骸之外。人这一生,如昙花一现。如草木春绿秋枯,如曦月东升西落。但偏偏这一生欲望却有很多。小时候溪头卧剥莲蓬,
话也不可说得太满,满必有所失,切忌交浅言深但凡需要你在对方和自己的利益之间做选择的关系,果断咬牙切割放弃。你耗得越久,就离地狱越近。稍有不慎就可能因为这个人,失去你生活的一切。从今往后请务必以自己为重,永远优先选择对自己有
人有德,必有福,能这样做的人,福报会越来越多!一个人的福报,决定了一生的所有。因为我们想要的所有东西,如钱财,名利,健康,平安,家庭幸福,婚姻美满,子孙出息等等,都可以用一个福字包括在内。虽然不可能十全十美,但是哪怕拥有一项,
浅谈幸福夜半儿啼,醒来胡思乱想,思及人,满足,高兴,快乐,幸福,是人之所往欲望,渴望,希望,梦想,是所往之图。温饱易使人满足,耳目声色易使人高兴,精神放松愉悦即是快乐,而幸福呢?是否是一切
世上最复杂的事莫过于人性人性是复杂的人前人后不一样。台上台下不一样。酒前酒后不一样。利益前后不一样。严肃正经的脸孔下,也许隐藏着一颗顽皮不安的内心。慈目善眉于众人前,转身在月黑风高时杀人越货。本该担负起救
心语新慰丨做自己喜欢的事,永远没有太晚的开始有时,去治愈常常,去帮助总是,去安慰这是百年前,一位医生的墓志铭。流传至今,依旧激励着一代又一代的医人。新华君虽不会诊病治疗,但也希望能通过自己小小的努力,给所有正在与病魔战斗的人