当前位置:网站首页>Go语言类型与接口的关系
Go语言类型与接口的关系
2022-08-03 19:52:00 【JIeJaitt】
在Go语言中类型和接口之间有一对多和多对一的关系,下面将列举出这些常见的概念,以方便读者理解接口与类型在复杂环境下的实现关系。
一个类型可以实现多个接口
一个类型可以同时实现多个接口,而接口间彼此独立,不知道对方的实
现。
网络上的两个程序通过一个双向的通信连接实现数据的交换,连接的一端称为一个 Socket。Socket 能够同时读取和写入数据,这个特性与文件类似。因此,开发中把文件和 Socket 都具备的读写特性抽象为独立的读写器概念。
Socket 和文件一样,在使用完毕后,也需要对资源进行释放。
把 Socket 能够写入数据和需要关闭的特性使用接口来描述,请参考下面的代码:
type Socket struct {
}
func (s *Socket) Write(p []byte) (n int, err error) {
return 0, nil
}
func (s *Socket) Close() error {
return nil
}
Socket 结构的 Write() 方法实现了 io.Writer 接口:
type Writer interface {
Write(p []byte) (n int, err error)
}
同时,Socket 结构也实现了 io.Closer 接口:
type Closer interface {
Close() error
}
使用 Socket 实现的 Writer 接口的代码,无须了解 Writer 接口的实现者是否具备 Closer 接口的特性。同样,使用 Closer 接口的代码也并不知道 Socket 已经实现了 Writer 接口,如下图所示。
在代码中使用 Socket 结构实现的 Writer 接口和 Closer 接口代码如下:
// 使用io.Writer的代码, 并不知道Socket和io.Closer的存在
func usingWriter( writer io.Writer){
writer.Write( nil )
}
// 使用io.Closer, 并不知道Socket和io.Writer的存在
func usingCloser( closer io.Closer) {
closer.Close()
}
func main() {
// 实例化Socket
s := new(Socket)
usingWriter(s)
usingCloser(s)
}
usingWriter() 和 usingCloser() 完全独立,互相不知道对方的存在,也不知道自己使用的接口是 Socket 实现的。
多个类型可以实现相同的接口
一个接口的方法,不一定需要由一个类型完全实现,接口的方法可以通过在类型中嵌入其他类型或者结构体来实现。也就是说,使用者并不关心某个接口的方法是通过一个类型完全实现的,还是通过多个结构嵌入到一个结构体中拼凑起来共同实现的。
Service 接口定义了两个方法:一个是开启服务的方法(Start()),一个是输出日志的方法(Log())。使用 GameService 结构体来实现 Service,GameService 自己的结构只能实现 Start() 方法,而 Service 接口中的 Log() 方法已经被一个能输出日志的日志器(Logger)实现了,无须再进行 GameService 封装,或者重新实现一遍。所以,选择将 Logger 嵌入到 GameService 能最大程度地避免代码冗余,简化代码结构。详细实现过程如下:
// 一个服务需要满足能够开启和写日志的功能
// 定义服务接口,一个服务需要实现 Start() 方法和日志方法
type Service interface {
Start() // 开启服务
Log(string) // 日志输出
}
// 日志器
// 定义能输出日志的日志器结构
type Logger struct {
}
// 实现Service的Log()方法
// 为 Logger 添加 Log() 方法,同时实现 Service 的 Log() 方法
func (g *Logger) Log(l string) {
}
// 游戏服务
// 定义 GameService 结构
type GameService struct {
// 在 GameService 中嵌入 Logger 日志器,以实现日志功能
Logger // 嵌入日志器
}
// 实现Service的Start()方法
// GameService 的 Start() 方法实现了 Service 的 Start() 方法
func (g *GameService) Start() {
}
此时,实例化 GameService,并将实例赋给 Service,代码如下:
var s Service = new(GameService)
s.Start()
s.Log(“hello”)
s 就可以使用 Start() 方法和 Log() 方法,其中,Start() 由 GameService 实现,Log() 方法由 Logger 实现。
边栏推荐
猜你喜欢

揭秘5名运维如何轻松管理数亿级流量系统

小马智行起诉擎天智卡:索赔6000万 彭军称要斗争到底

Interview Blitz: What Are Sticky Packs and Half Packs?How to deal with it?

FreeRTOS中级篇

深入理解JVM-内存结构

华为设备配置VRRP负载分担

钱江摩托某型号产品ECU货不对版 消费者知情权应如何保障?

调用EasyCVR接口时视频流请求出现404,并报错SSL Error,是什么原因?

怎么将自己新文章自动推送给自己的粉丝(巨简单,学不会来打我)

Line the last time the JVM FullGC make didn't sleep all night, collapse
随机推荐
谁的孙子最多II
自定义form表单验证
Introduction to Cosine Distance
Use ControlTemplate or Style from resource file in WPF .cs and find the control
钱江摩托某型号产品ECU货不对版 消费者知情权应如何保障?
epoll + 线程池 + 前后置服务器分离
matplotlib画polygon, circle
Solidity智能合约开发 — 4.1-合约创建和函数修饰器
开源生态研究与实践| ChinaOSC
pg_memory_barrier_impl in Postgresql and C's volatile
The effective square of the test (one question of the day 7/29)
详解AST抽象语法树
DeepMCP网络详解
LeetCode 622. 设计循环队列
百利药业IPO过会:扣非后年亏1.5亿 奥博资本是股东
汉源高科8光口12电口交换机千兆8光8电12电16电网管型工业以太网交换机
亚马逊云科技 Build On 2022 - AIot 第二季物联网专场实验心得
嵌入式分享合集27
演讲议题及嘉宾重磅揭晓,TDengine 开发者大会推动数据技术“破局”
单调栈及其应用