golang的接口是什么

Golang 中,接口是一种类型,它是由一组办法签名组成的笼统集合。接口界说了目标应该具有的行为,而不关心目标的详细完成。完成接口的目标必须完成接口界说的所有办法,这样才干称为该接口的完成。

什么情况下要用接口

  1. 界说通用的办法:接口能够界说一组通用的办法,以便在不同类型中完成。这样能够让代码更加通用,削减冗余。比方,文件体系中的 Read 和 Write 办法便是一种通用的办法,能够在不同类型的文件目标上完成。另一个比如是 fmt.Stringer 接口,它界说了一个 String() 办法,能够返回一个字符串表示目标。
  2. 完成多态:接口能够完成多态,也便是在不同类型的目标上履行相同的操作。通过接口,不同类型的目标能够完成相同的接口,然后在履行相同的操作时,能够调用不同类型的目标的办法。例如,io.Reader 和 io.Writer 接口能够用来读取和写入数据,不同类型的目标能够完成这些接口,然后能够运用相同的代码来处理不同类型的数据。
  3. 松耦合的规划:接口能够完成松耦合的规划,也便是在接口的界说中,只界说了目标应该具有的行为,而不关心目标的详细完成。这使得咱们能够轻松地替换目标的完成,而不必忧虑其他部分的代码会受到影响。例如,在测验中,咱们能够运用模仿目标来替换真实的目标,然后测验代码的逻辑,而不必忧虑对其他部分的代码产生影响。
  4. 完成插件化架构:运用接口能够完成插件化架构,也便是将代码分解为小的模块,每个模块完成一个或多个接口。这样能够使得代码更加灵敏,能够在运转时动态加载和卸载模块。例如,一个应用程序能够界说一个插件接口,其他开发人员能够编写插件并完成该接口,然后能够将这些插件动态地加载到应用程序中。

运用接口能够提高代码的灵敏性和可重用性,然后削减代码的冗余和提高代码的可维护性。在 Golang 中,接口是一种非常强大和灵敏的特性,建议在开发中广泛运用。

实战事例

多态的比如

场景:在运维开发中,可能需求办理不同类型的服务器,如物理服务器、虚拟机和容器。这些服务器可能具有不同的特点和办理办法。在这种情况下,能够运用接口来完成多态,然后在不同类型的服务器上履行相同的操作。

packagemain
//界说服务器接口
typeServerinterface{
GetName()string
GetIP()string
Reboot()error
InstallPackage(namestring)error
}
//物理服务器完成
typePhysicalServerstruct{
Namestring
IPstring
//其他物理服务器的特点
}
func(s*PhysicalServer)GetName()string{
returns.Name
}
func(s*PhysicalServer)GetIP()string{
returns.IP
}
func(s*PhysicalServer)Reboot()error{
//运用IPMI等技术重启物理服务器的详细完成
returnnil
}
func(s*PhysicalServer)InstallPackage(namestring)error{
//运用yum、apt等东西安装软件包的详细完成
returnnil
}
//虚拟机完成
typeVirtualMachinestruct{
Namestring
IPstring
//其他虚拟机的特点
}
func(s*VirtualMachine)GetName()string{
returns.Name
}
func(s*VirtualMachine)GetIP()string{
returns.IP
}
func(s*VirtualMachine)Reboot()error{
//运用虚拟化办理东西重启虚拟机的详细完成
returnnil
}
func(s*VirtualMachine)InstallPackage(namestring)error{
//运用操作体系的包办理东西安装软件包的详细完成
returnnil
}
//容器完成
typeContainerstruct{
Namestring
IPstring
//其他容器的特点
}
func(s*Container)GetName()string{
returns.Name
}
func(s*Container)GetIP()string{
returns.IP
}
func(s*Container)Reboot()error{
//运用容器办理东西重启容器的详细完成
returnnil
}
func(s*Container)InstallPackage(namestring)error{
//运用容器办理东西安装软件包的详细完成
returnnil
}
//主函数中运用不同类型的服务器目标
funcmain(){
//创立不同类型的服务器目标
physicalServer:=&PhysicalServer{}
virtualMachine:=&VirtualMachine{}
container:=&Container{}
//调用不同类型的服务器目标的办法
err:=physicalServer.InstallPackage("nginx")
iferr!=nil{
//处理过错
}
err=virtualMachine.Reboot()
iferr!=nil{
//处理过错
}
err=container.InstallPackage("mysql")
iferr!=nil{
//处理过错
}
}

界说通用办法的比如

场景:一个常见的运维场景是办理多个服务器上的进程。在这种情况下,能够界说一个Process接口,它包括发动、中止和重启进程的办法。这个接口能够在不同类型的进程目标中完成,如Docker容器、操作体系进程或Kubernetes中的Pod。

//界说进程接口
typeProcessinterface{
Start()error
Stop()error
Restart()error
}
//容器进程完成
typeContainerProcessstruct{
ContainerIDstring
//其他容器进程的特点
}
func(c*ContainerProcess)Start()error{
//运用DockerAPI发动容器进程的详细完成
returnnil
}
func(c*ContainerProcess)Stop()error{
//运用DockerAPI中止容器进程的详细完成
returnnil
}
func(c*ContainerProcess)Restart()error{
//运用DockerAPI重启容器进程的详细完成
returnnil
}
//操作体系进程完成
typeOSProcessstruct{
PIDint
//其他操作体系进程的特点
}
func(o*OSProcess)Start()error{
//运用体系API发动操作体系进程的详细完成
returnnil
}
func(o*OSProcess)Stop()error{
//运用体系API中止操作体系进程的详细完成
returnnil
}
func(o*OSProcess)Restart()error{
//运用体系API重启操作体系进程的详细完成
returnnil
}
//KubernetesPod完成
typeKubernetesPodstruct{
PodNamestring
//其他KubernetesPod的特点
}
func(k*KubernetesPod)Start()error{
//运用KubernetesAPI发动Pod进程的详细完成
returnnil
}
func(k*KubernetesPod)Stop()error{
//运用KubernetesAPI中止Pod进程的详细完成
returnnil
}
func(k*KubernetesPod)Restart()error{
//运用KubernetesAPI重启Pod进程的详细完成
returnnil
}
//主函数中运用不同类型的进程目标
funcmain(){
//创立不同类型的进程目标
container:=&ContainerProcess{}
osProcess:=&OSProcess{}
kubernetesPod:=&KubernetesPod{}
//调用不同类型的进程目标的办法
err:=container.Start()
iferr!=nil{
//处理过错
}
err=osProcess.Stop()
iferr!=nil{
//处理过错
}
err=kubernetesPod.Restart()
iferr!=nil{
//处理过错
}
}

这个示例代码演示了如安在不同类型的进程目标中完成Process接口。由于Process接口界说了一组通用的办法,能够通过一个通用的函数或东西类来办理不同类型的进程目标,然后削减冗余的代码。

松耦合的比如

场景:在运维开发中,假定要办理不同的云渠道服务,例如腾讯云、阿里云、移动云等。每个云渠道供给的服务可能会有不同的完成办法和API接口,可是它们都具有相似的行为和功能,例如创立、删去、发动和中止服务实例,获取实例的状态和日志等。在这种情况下,咱们能够运用Go言语的接口来完成松耦合的规划,将不同云渠道的服务完成封装在各自的结构体中,并且让它们都完成相同的接口。这样,咱们的代码就能够运用相同的函数来处理所有不同的云渠道服务,而不必关心详细的完成细节。

packagemain
//界说CloudService接口
typeCloudServiceinterface{
CreateInstance()error
DeleteInstance()error
StartInstance()error
StopInstance()error
}
//腾讯云服务完成
typeTencentCloudServicestruct{
//完成TencentCloudService特定的特点和办法
}
func(tencent*TencentCloudService)CreateInstance()error{
//运用腾讯云API创立服务实例的详细完成
returnnil
}
func(tencent*TencentCloudService)DeleteInstance()error{
//运用腾讯云API删去服务实例的详细完成
returnnil
}
func(tencent*TencentCloudService)StartInstance()error{
//运用腾讯云API发动服务实例的详细完成
returnnil
}
func(tencent*TencentCloudService)StopInstance()error{
//运用腾讯云API中止服务实例的详细完成
returnnil
}
//阿里云服务完成
typeAliCloudServicestruct{
//完成AliCloudService特定的特点和办法
}
func(ali*AliCloudService)CreateInstance()error{
//运用阿里云API创立服务实例的详细完成
returnnil
}
func(ali*AliCloudService)DeleteInstance()error{
//运用阿里云API删去服务实例的详细完成
returnnil
}
func(ali*AliCloudService)StartInstance()error{
//运用阿里云API发动服务实例的详细完成
returnnil
}
func(ali*AliCloudService)StopInstance()error{
//运用阿里云API中止服务实例的详细完成
returnnil
}
//移动云服务完成
typeMobileCloudServicestruct{
//完成MobileCloudService特定的特点和办法
}
func(mobile*MobileCloudService)CreateInstance()error{
//运用移动云API创立服务实例的详细完成
returnnil
}
func(mobile*MobileCloudService)DeleteInstance()error{
//运用移动云API删去服务实例的详细完成
returnnil
}
func(mobile*MobileCloudService)StartInstance()error{
//运用移动云API发动服务实例的详细完成
returnnil
}
func(mobile*MobileCloudService)StopInstance()error{
//运用移动云API中止服务实例的详细完成
returnnil
}
//主函数中运用不同的云服务完成
funcmain(){
//创立不同的云服务完成
tencentCloud:=&TencentCloudService{}
aliCloud:=&AliCloudService{}
mobileCloud:=&MobileCloudService{}
//接着就能够调用服务完成的办法...

}

完成插件化架构的比如

场景:假定有一个监控体系,需求完成不同类型的监控插件

  • CPU 监控插件,能够获取 CPU 运用率。
  • 磁盘监控插件,能够获取磁盘运用情况。
  • 内存监控插件,能够获取内存运用情况。 咱们将编写一个主程序,以及三个插件,每个插件完成一个名为 Monitor 的接口,用于获取监控数据。
  1. 编写主程序
packagemain
import(
"fmt"
"plugin"
)
typeMonitorinterface{
GetData()(string,error)
}
funcmain(){
//加载插件
p,err:=plugin.Open("./cpu_monitor.so")
iferr!=nil{
panic(err)
}
//获取插件实例
dataSourceSymbol,err:=p.Lookup("CpuMonitorInstance")
iferr!=nil{
panic(err)
}
dataSource,ok:=dataSourceSymbol.(Monitor)
if!ok{
panic("plugindoesnotimplementDataSource")
}
//运用插件获取数据
data,err:=dataSource.GetData()
iferr!=nil{
panic(err)
}
fmt.Println(data)
}

主程序界说了一个名为 Monitor 的接口,用于获取监控数据。在 main 函数中,咱们先加载一个名为 cpu_plugin.so 的插件,然后获取插件实例,并将其强制转换为 Monitor 接口类型。接下来,咱们调用 GetData 办法获取 CPU 监控数据,并输出到控制台。

  1. 编写插件 下面是一个名为 cpu_plugin.go 的插件,它完成了 Monitor 接口,用于获取 CPU 监控数据。
packagemain
import(
"fmt"
"time"
)
typeCpuMonitorstruct{}
func(mCpuMonitor)GetData()(string,error){
//模仿获取CPU运用率
usage:=fmt.Sprintf("CPUusage:%d%%",30)
time.Sleep(time.Second)
returnusage,nil
}
varCpuMonitorInstanceCpuMonitor

在插件中,咱们完成了 Monitor 接口,并界说了一个名为 CpuMonitorInstance 的变量,用于导出插件实例。

  1. 编译插件 运用以下指令将插件编译为同享目标文件:
gobuild-buildmode=plugin-ocpu_monitor.socpu_monitor.go
  1. 运转看看效果,发现现已成功加载插件
[root@workhosttemp]#gorunmain.go
CPUusage:30%

编写内存、磁盘的监控插件也是按这个套路完成即可。留意了,我这儿获取cpu运用率的插件仅仅模仿代码,并没有真实完成。实际上,能够运用Golang标准库中的runtime包就能够获取到cpu运用率。

本文转载于WX大众号:不背锅运维(喜欢的盆友关注咱们):mp.weixin.qq.com/s/bwkK3Yw02…