版权声明:我已加入“维权骑士”(http://rightknights.com)的版权保护计划,知乎专栏“网路行者”下的所有文章均为我本人(知乎ID:弈心)原创,未经允许不得转载。

如果你喜欢我的文章,请关注我的知乎专栏“网路行者”https://zhuanlan.zhihu.com/c_126268929, 里面有更多像本文一样深度讲解计算机网络技术的优质文章。


接口基本概念

前面在讲解结构体的时候提到了:结构体允许我们自定义一个新的数据类型。在Go语言中,接口(Interfaces)和结构体一样,都属于自定义类型(User-defined Type)。

接口用来定义一个或多个方法签名(method signatures),换句话说,接口是方法的集合。重点:接口本身只声明方法及其返回的值的类型,并不会定义该方法的实施细节(implementation details),也就是说接口不会告诉我们这个方法具体做了些什么,因此接口是抽象的(Go语言中唯一一种抽象类型)。正因如此,不同于结构体,我们不能创建接口的实例,但是可以创建类型为接口的变量。

创建接口

这里我们创建了一个叫做demo_interface的接口,该接口定义了demo_method1()和demo_method2()两种方法。 demo_method1()和demo_method2()在接口里又被叫做方法签名。

实现接口

前面讲了,接口本身只定义方法及其返回的值的类型,并不会定义该方法的实施细节(implementation details),也就是说接口不会告诉我们这个方法具体做了些什么。

和其他语言不同,Go中的接口是隐式实现的,Go语言中没有直接用来实现接口的关键词。为了实现接口,我们还必须额外创建自定义方法来实现接口里声明的所有方法,注意必须是实现接口里声明的所有方法,上面我们创建的demo_interface这个接口里定义了demo_method1()和demo_method2()两个方法,我们必须将它们都实现了才能实现接口,缺一不可。

下面通过两个例子来说明如何实现接口。

简单例子

网络运维例子

看了上面的简单例子后,作为网络工程师的你可能理解了如何在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,最后我们创建一个叫做CompareIosUptime()的自定义函数用来比较两台设备谁的uptime时间更久。

实现上述需求的代码如下。

同样的道理,我们创建一个叫做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函数完全一样。

实现上述需求的代码如下。

至此,前面提到的三个需求我们已经实现了前两个:

  • 比较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的接口,接口代码如下。

通过创建这个接口,我们巧妙地让本来不属于同一类型的IOS类型和NX_OS类型此时同属于CiscoDevice这个接口类型,随后我们再创建一个叫做CompareIosNxosUptime()的函数,该函数里需要两个参数来分别代表IOS交换机和NX-OS路由器,两个参数的数据类型均为CiscoDevice(接口类型),然后就可以顺利地比较它们的uptime了,代码如下。