当前位置:网站首页>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 实现。
边栏推荐
- Solution for no navigation bar after Word is saved as PDF
- 子结点的数量(2)
- 京东云发布新一代分布式数据库StarDB 5.0
- 「游戏建模干货」建模大师几步操作,学习经典,赶紧脑补一下吧
- Introduction to Cosine Distance
- 百利药业IPO过会:扣非后年亏1.5亿 奥博资本是股东
- MySQL master-slave, 6 minutes you master!
- 消除对特权账户的依赖使用Kaniko构建镜像
- 花 30 美金请 AI 画家弄了个 logo,网友:画得非常好,下次别画了!
- 【飞控开发高级教程6】疯壳·开源编队无人机-AI语音控制
猜你喜欢

async 和 await 原来这么简单

【统计机器学习】线性回归模型
手把手教你定位线上MySQL慢查询问题,包教包会

从文本匹配到语义相关——新闻相似度计算的一般思路

1161 最大层内元素和——Leetcode天天刷【BFS】(2022.7.31)

Internet Download Manager简介及下载安装包,IDM序列号注册问题解决方法

入门3D建模基础教程详细分解

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

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

List类的超详细解析!(超2w+字)
随机推荐
php根据两点经纬度计算距离
FreeRTOS中级篇
后台图库上传功能
Pytorch GPU 训练环境搭建
单调栈及其应用
MySQL 主从,6 分钟带你掌握!
149. The largest number on a straight line, and check the set
危化企业双重预防机制数字化建设进入全面实施阶段
一种能有效缓解环境噪声对音频质量干扰的方案
Interview Blitz: What Are Sticky Packs and Half Packs?How to deal with it?
Shell programming loop statement
ADS 2023 Download Link
Postgresql snapshot optimization Globalvis new system analysis (performance greatly enhanced)
使用 ReportLab 绘制 PDF
Kettle 读取 Excel 数据输出到 Oracle 详解
演讲议题及嘉宾重磅揭晓,TDengine 开发者大会推动数据技术“破局”
Unity gets the actual coordinates of the ui on the screen under the canvas
简易电子琴设计(c语言)
622 设计循环队列——Leetcode天天刷【循环队列,数组模拟,双指针】(2022.8.2)
安装anaconda并创建虚拟环境