Golang(5)-接口

5个Go接口常见错误及避免方法 方面不良实践更佳实践接口设计不必要地嵌入接口定义独立的接口灵活性强制不必要的方法允许选择性使用接口清晰度模糊的接口意图每个接口都有明确的目的Effective Go - 接口嵌入方面不良实践更佳实践接口规模方法繁多,实现困难方法精简,目标明确可测试性需要模拟所有方法仅模拟必要部分灵活性强制实现不必要的方法允许选择性实现Effective Go - 接口方面不良实践更佳实践接口用法导出供单一实现使用直接使用具体类型代码清晰度掩盖实现细节清晰且直接。 阅读详情


更多关于Golang核心编程知识的文章请看:Golang核心编程(0)-目录页


一、其他语言的侵入式接口

Go语言的接口并不是其他语言(C++、Java、C#等)中所提供的接口概念。
在Go语言出现之前,接口主要作为不同组件之间的契约存在。对契约的实现是强制的,你必须声明你的确实现了该接口。为了实现一个接口,你需要从该接口继承:

interface IFoo {
void Bar();
}
class Foo implements IFoo { // Java文法
// ...
}
class Foo : public IFoo { // C++文法
// ...
}
IFoo* foo = new Foo;

即使另外有一个接口 IFoo2 实现了与 IFoo 完全一样的接口方法甚至名字也叫 IFoo 只不过位于不同的名字空间下,编译器也会认为上面的类 Foo 只实现了 IFoo 而没有实现 IFoo2 接口。

这类接口我们称为侵入式接口。“侵入式”的主要表现在于实现类需要明确声明自己实现了某个接口。这种强制性的接口继承是面向对象编程思想发展过程中一个遭受相当多置疑的特性。

二、 Golang的非侵入式接口

在Go语言中,一个类只需要实现了接口要求的所有函数,我们就说这个类实现了该接口,例如:

type File struct {
// ...
}
func (f *File) Read(buf []byte) (n int, err error)
func (f *File) Write(buf []byte) (n int, err error)
func (f *File) Seek(off int64, whence int) (pos int64, err error)
func (f *File) Close() error

这里我们定义了一个 File 类,并实现有 Read() 、 Write() 、 Seek() 、 Close() 等方法。设想我们有如下接口:

type IFile interface {
Read(buf []byte) (n int, err error)
Write(buf []byte) (n int, err error)
Seek(off int64, whence int) (pos int64, err error)
Close() error
}

type IReader interface {
Read(buf []byte) (n int, err error)
}

type IWriter interface {
Write(buf []byte) (n int, err error)
}

type ICloser interface {
Close() error
}

尽管 File 类并没有从这些接口继承,甚至可以不知道这些接口的存在,但是 File 类实现了
这些接口,可以进行赋值:

var file1 IFile = new(File)
var file2 IReader = new(File)
var file3 IWriter = new(File)
var file4 ICloser = new(File)

Go的非侵入式接口有许多好处:

其一,在Go中,类的继承树并无意义,你只需要知道这个类实现了哪些方法,每个方法是啥含义就足够了。
其二,实现类的时候,只需要关心自己应该提供哪些方法,不用再纠结接口需要拆得多细才
合理。接口由使用方按需定义,而不用事前规划。
其三,不用为了实现一个接口而导入一个包,因为多引用一个外部的包,就意味着更多的耦
合。接口由使用方按自身需求来定义,使用方无需关心是否有其他模块定义过类似的接口。

三、 接口判断

接口查询语法,代码如下:

var file1 Writer = ...
if file5, ok := file1.(two.IStream); ok {
...
}

这个 if 语句检查 file1 接口指向的对象实例是否实现了 two.IStream 接口,如果实现了,则执行特定的代码。

接口查询是否成功,要在运行期才能够确定。它不像接口赋值,编译器只需要通过静态类型检查即可判断赋值是否可行。

四、类型查询

在Go语言中,还可以更加直截了当地询问接口指向的对象实例的类型,例如:

	var v1 interface{} = ...
	switch v := v1.(type) {
	case int: // 现在v的类型是int
	case string: // 现在v的类型是string
	...
}

五、接口组合

Go语言同样支持接口组合。我们已经介绍过Go语言包中 io.Reader接口和 io.Writer 接口,接下来我们再介绍同样来自于 io 包的另一个接口 io.ReadWriter :

	// ReadWriter接口将基本的Read和Write方法组合起来
	type ReadWriter interface {
	Reader
	Writer
	}

这个接口组合了 Reader 和 Writer 两个接口,它完全等同于如下写法:

	type ReadWriter interface {
	Read(p []byte) (n int, err error)
	Write(p []byte) (n int, err error)
	}

因为这两种写法的表意完全相同: ReadWriter 接口既能做 Reader 接口的所有事情,又能做
Writer 接口的所有事情。在Go语言包中,还有众多类似的组合接口,比如 ReadWriteCloser 、ReadWriteSeeker 、 ReadSeeker 和 WriteCloser 等。
可以认为接口组合是类型匿名组合的一个特定场景,只不过接口只包含方法,而不包含任何成员变量。

六、Any 类型

由于Go语言中任何对象实例都满足空接口 interface{} ,所以 interface{} 看起来像是可
以指向任何对象的 Any 类型,如下:

var v1 interface{} = 1 // 将int类型赋值给interface{}
var v2 interface{} = "abc" // 将string类型赋值给interface{}
var v3 interface{} = &v2 // 将*interface{}类型赋值给interface{}
var v4 interface{} = struct{ X int }{1}
var v5 interface{} = &struct{ X int }{1}
利用Golang实现对接ChatGPT3.5模型接口-并且无需FQ已经使用代理域名 GPT3.5的模型接口已经出来了一段时间,之前使用Vue.js对接过该模型的接口 现在使用Golang来对接实现一下这个接口 对第三方库github.com/sashabaranov/go-openai 进行二次封装 域名部分找了一个代理域名,要不然国内服务器访问不通 import ( "context" "fmt" "github.com/sashabaranov/go-o... 阅读详情

相关推荐

Neurocomputing 投稿指南

Generation Information:选择论文所属领域。上传附件(利益声明,手稿,摘要)审稿人偏好:可以选择期待的审稿人。

qq_41174671的博客 2万+

go运行时状态信息

go运行时状态信息 内存 runtime.ReadMemStats(&ms) 获取内存分配信息,可以定时收集,发送给时序数据库做监控统计 gc 数据 ReadGCStats 获取最近的GC统计信息,可以定时收集,发送给时序数据库做监控统计 协程数 runtime.NumGoroutine 获取当前协程数,可以定时收集,发送给时序数据库做监控统计 panic 堆栈信息 日志查询 pporf 实现 flag.StringVar(&cpuprofile, "cpuprofile", ""

hallyz的博客 1287

【无机纳米材料科研制图——OriginLab 0205】Origin对BET吸附/脱附曲线及孔径分布制图...

此篇,我们来分享如何对BET数据进行处理和制图。 一、等温吸脱附曲线绘制 1)找到等温吸脱附文件。 一半来说,对一个样品测一次BET,会产生很多数据,具体因仪器而异。我这里的数据主要有两个文件夹,一个脱附,一个吸附,吸附文件夹中多了一个等温吸脱附的文件夹。而这...

XD_Yangf的博客 803

GOLang-判断进程是否存在

利用GO打算写一个进程检测工具,发现并没有直接可以获取进程的信息的方式,后经过查找,决定采用命令的方式进行处理,关键代码如下: buf := bytes.Buffer{} cmd := exec.Command("wmic", "process", "get", "name,executablepath") cmd.Stdout = &buf cmd...

IT旅途 1万+

别再只调OpenCV参数了!手把手教你用Python bm3d库搞定图像去噪(附完整代码与效果对比)

本文详细介绍了BM3D算法在图像去噪中的高级应用,通过Python bm3d库实现超越OpenCV传统方法的去噪效果。文章包含完整代码示例、参数调优技巧及工程化应用场景,帮助开发者掌握这一被称为'传统方法天花板'的技术,显著提升图像信噪比和细节保留能力。

weixin_28362173的博客 367

直击高频编程考点:字符串知识及经典算法题总结

字符串相关基本练习题总结(最长公共子串、最长回文子串、最长无重复字符子串、最小覆盖子串、字符串相乘、中文数字表达转实际数字格式等)

曾经“等你生日那天”都遥远得像未来,如今却可欢愉的挥手说“下个十年见” 172万+

如何检查服务是否运行_如何在 Golang 中为 RESTful 微服务创建健康检查

想象一下,您最近发布并部署了一段很酷的 RESTful 微服务,您已经使用了一段时间。您松了一口气却听到 Ops 团队说您的服务不稳定。您真的很确定服务应该没问题,可能是它依赖的服务有问题。那该怎么办?健康检查将来拯救你。它是您的服务返回状态的端点,包括您的服务直接依赖的所有外部服务的连接状态。在这篇文章中,我将展示如何为在多个节点上运行的微服务创建健康检查,该服务将其状态存储在 MongoDB ...

weixin_39520880的博客 983

操作系统权限提升(十五)之绕过UAC提权-基于白名单DLL劫持绕过UAC提权

先将操作在本地执行,使用procmon进行监控,过滤DLL和 NAME NOT FOUND ,寻找可以替换的DLL文件,注意文件的权限是否可以在目录写入,可以看到在C盘的tools目录的文件中有一个srrstr.dll被调用,但是没有加载,我们生成恶意的DLL文件看看是否可以被劫持。在Windows中许多应用程序并不是一个完整的可执行文件,它们被分割成一些相对独立的动态链接库文件,即dll文件,放置于系统中,个人理解类似于我们编程中引入的模块。将我们生成的DLL文件改名为我们要劫持的DLL文件名。

把自己活成一道光,因为你不知道,谁会借着你的光,走出了黑暗。请保持心中的善良,因为你不知道,谁会借着你的善良,走出了绝望。请保持你心中的信仰,因为你不知道,谁会借着你的信仰,走出了迷茫。请相信自己的力量,因为你不知道,谁会因为相信你,开始相信了自己.... 1874

【知识梳理】Go语言核心编程

基础知识 Go语言就是为了解决编程语言对并发支持不友好、编译速度慢、编程复杂这三个问题而诞生的 语言特性对比:p4 package main import "fmt" func main() { fmt.Printf("Hello world") } Go源代码特性解读: 源代码以.go为后缀 源程序默认为UTF-8编码 标识符区分大小写 语句结尾的分号...

victorzzzz的专栏 987

AI辅助Android开发:从传统到智能化的技术演进

AI辅助开发的核心在于利用算法模型自动化或优化传统任务。在Android开发中,AI可应用于需求分析、设计、编码、测试和维护各阶段。需求分析:AI工具如基于NLP的模型(例如GPT系列)可解析用户需求文档,自动生成用户故事和原型设计。假设产品需求为“开发一个航班查询应用”,AI能提取关键词,输出UML图或伪代码。代码生成:使用AI代码助手(如GitHub Copilot),工程师输入自然语言描述,AI生成Java/Kotlin代码片段。

郑伟强dev的专栏 137

在 SAP ABAP 生态中偏爱面向对象,而不是过程式堆叠

本文探讨了ABAP开发中过程式与面向对象编程的共存现状及优化方向。文章指出,虽然过程式编程在ABAP中仍广泛存在,但随着业务复杂度提升,面向对象编程在可维护性、可测试性和重构便利性方面展现出明显优势。作者建议将过程式代码作为"适配层",仅负责输入输出转换,而将核心业务逻辑封装在类中。文章通过实际案例展示了这种架构如何提高交付效率,并提供了将Function Module转化为"薄包装"的具体实现方案,强调面向对象设计在SAP Gateway和RAP等现代架构中的重要性

2007 年 ~ 2025 年,深耕 SAP 技术 18 年 137

3、Go语言核心编程(高级篇)

面向对象、文件、tcp、单元测试、协程和管道

m0_73293551的博客 3226

【Burp入门第三十七篇】AutoRepeater插件安装使用教程+越权实战案例

AutoRepeater 通过接收满足特定条件的请求,按照预设的基础替换规则对请求进行处理。在接收到匹配请求后,它首先应用基础替换,然后针对每个定义的替换创建请求副本并应用该替换操作,从而实现对不同参数的修改和请求的重复发送,以此来全面检测 Web 应用的授权情况。1、自动化请求重复:能自动复制、修改并重发 HTTP 请求,避免了手动重复操作的繁琐,大大提高了 Web 应用授权测试的效率。2、灵活参数替换:可灵活改变邮箱地址、账号身份、角色、URL 和 CSRF 令牌等关键参数。

等风来 2037

Go的面向接口——Golang学习笔记5

文章目录duck typing的概念静态语言和动态语言duck typing解释不同语言中实现duck typing参考链接 Golang是面向接口的编程语言,相比其他面向对象的编程语言,其并没有继承和多态; Golang仅仅支持封装; Golang实现面向对象(继承和多态,封装)需要利用接口完成; duck typing的概念 静态语言和动态语言 1. 静态语言(强类型语言) 静态语言是在编译时变量的数据类型即可确定的语言,多数静态类型语言要求在使用变量之前必须声明数据类型。 例如:C++、Jav

jianming21的博客 365

STM32F407中文手册

STM32f407中文手册 本参考手册面向应用开发人员,提供有关使用 STM32F405xx/07xx、STM32F415xx/17xx、 STM32F42xxx 和 STM32F43xxx 微控制器存储器与外设的完整信息。STM32F405xx/07xx、STM32F415xx/17xx、STM32F42xxx 和 STM32F43xxx 构成一个微 控制器系列,各产品具有不同的存储器大小、封装和外设。有关订购信息以及器件的机械与电气特性,请参见数据手册。有关 ARM Cortex™-M4F 内核的信息,请参见《Cortex™-M4F 技术参考手册》。

老版QQ原生表情gif动态

这是老版的QQ表情,不过全是动态的的,Windows照片查看器是不会动的,可以右击用浏览器打开查看,再说一遍是老版的,只是分享给宁愿用老版也要动态的人。

go interface类型转换_Golang系列5 | Interface接口&map类型

go语言接口(interface),类似其他语言的接口的作用,主要用于定义一组函数(方法)签名,不包括实现。1.接口定义语法:type 接口类型名 interface { 函数签名列表}例子:// 定义Abser接口类型,里面包含一个Abs函数签名定义,不包括函数实现。type Abser interface { Abs() float64}2.接口实现go语言实现接口,采用...

weixin_39611754的博客 4746

IDEA的使用指南

IDEA基于java的使用手册,可以最快速的上手,在使用中不断的丰富自己的使用技巧.

go调用mysql接口_Golang连接使用MySql5.7数据库完整步骤

标签:创建数据库、用户以及修改密码在终端中输入命令,启动数据库:service mysql start以下是在MySql中执行的操作。为防止修改系统的数据库,我们需要新建一个新的数据库:CREATE DATABASE test_db;切换到新建的数据库:use test_db;在该数据库中新建一个表单,其中uid是自动增长的主键:CREATE TABLE "userinfo" ('uid' INT...

weixin_39622332的博客 326

假人有限元模型

假人模型,车辆碰撞假人有限元模型,适合做乘员安全的研究者利用

第三方接口调用的限流艺术:Golang中uber-go/ratelimit的5个高阶用法

本文深入探讨了在Golang中使用uber-go/ratelimit库进行第三方接口调用的限流艺术。文章重点解析了五个高阶用法,包括阻塞机制控制、动态速率调整、Context超时处理、连接池协同以及智能错误重试策略,旨在帮助开发者构建稳定、高效且严格遵守外部QPS限制的服务调用层。

emacs5lisp的博客 170

golang学习笔记5——接口

接口的声明 golang中的接口声明方式如下: type 接口名 interface { 方法名(参数) 返回值 } 例子: // Writer接口 type Writer interface { // Write方法,参数为一个字符串 Write(s string) } // Stringer接口 type Stringer interface { // String方法,参数为空,...

记录技术,记录生活 3128

【Go语言核心手册5】接口

​5.1 接口实现 一个接口类型定义了一套方法,如果一个具体类型要实现该接口,那么必须实现接口类型定义中的所有方法。有同学可能觉得,这个概念很简单啊,先看个示例: type tester interface { test() string() string}type data struct {}func (*data) test() {}func (data) string() string { return ""}func main() { var d data //

飞楼踏梦 277

5、go语言:面向接口

1、duck typing的概念: type Traversal interface{ Traverse() } func main(){ traversal := getTraversal() traversal.Traverse() } duck typing原话:“像鸭子走路,像鸭子叫(长得像鸭子),那么就是鸭子” 描述事物的外部行为而非内部结构 严格说go属于结构化类型系统,类似...

u012573437的博客 175

深入学习golang(5)—接口

接口 概述 如果说goroutine和channel是Go并发的两大基石,那么接口是Go语言编程中数据类型的关键。在Go语言的实际编程中,几乎所有的数据结构都围绕接口展开,接口是Go语言中所有数据结构的核心。 Go语言中的接口是一些方法的集合(method set),它指定了对象的行为:如果它(任何数据类型)可以做这些事情,那么它就可以在这里使用。 type Reader interface { ...

weixin_33922672的博客 92

go语言基础5_接口

无论是设计文档还是实际编程,接口都是一个绕不开的概念 接口的定义 接口(硬件类接口)是指同一计算机不同功能层之间的通信规则称为接口。 接口(软件类接口)是指对协定进行定义的引用类型。其他类型实现接口,以保证它们支持某些操作。接口指定必须由类提供的成员或实现它的其他接口。与类相似,接口可以包含方法、属性、索引器和事件作为成员。 接口文档 项目开发中,如果涉及前后端分离开发,app开发需要前后端工程师共同定义接口,编写接口文档,然后继续开发并维护。 接口规范中接口分为四部分:方法、uri、请求参数、返回参.

m0_38024097的博客 331

Golang基础5-指针、结构体、方法、接口

Golang基础5-指针、结构体、方法、接口

m0_61973596的博客 1307
上一篇: Golang(2)-类型系统
下一篇: Golang(6)-协程和通道
BoringRong
BoringRong 领域专家: 后端开发技术领域 领域专家: 后端开发技术领域
博客等级 码龄9年 2万+粉丝 386原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

BoringRong

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值