当前位置: 首页 > news >正文

GO语言--接口(interface)的定义及使用

接口定义

接口也是一种数据类型,它代表一组方法的集合。

接口是非侵入式的。即接口设计者无需知道接口被哪些类型实现,而接口使用者只需知道实现怎样的接口,并且无须指明实现哪一个接口。编译器在编译时就会知道哪个类型实现哪个接口,或者接口该由谁来实现。

具体实现

直接来看例子。首先接口方法的功能必须通过结构体来实现。例子如下

package mainimport "fmt"type action interface {walk(name string)
}
type sinner struct {name string
}func setName(s *sinner, name string) sinner {s.name = namereturn *s
}
func (s *sinner) walk(name string) {fmt.Printf("%v is walking\n", s.name)
}
func walking(a action, name string) {a.walk(name)
}
func main() {var (tmp sinner)setName(&tmp, "Ishmael")walking(&tmp, tmp.name)
}

运行结果为

 Ishmael is walking

可以看到我们并没有直接调用walk()方法,而是通过walking()函数去调用walk()函数。

在主函数中,将sinner结构体与action接口绑定的是这一步。我们将sinner结构体实例化(给结构里的name赋值"Ishmael",然后生成实例化变量tmp。再将tmp的地址传入到walking()函数中。此时,由于walking()函数中变量a的类型为action,而我们传入的变量tmp类型为(*sinner),结构体sinner便与接口action绑定在了一起。

	walking(&tmp, tmp.name)

“鸭子类型”(Duck Typing)。

只要走起来像鸭子,或者游泳姿势像鸭子,或者叫声像鸭子,那么它就是一只鸭子。用官方术语来解释:鸭子类型只关注事物的外部行为而非内部结构。

我们将接口与结构体的绑定过程通过函数实现。只要我们传入结构体的实例化变量,函数就能自动执行接口方法。这样就不需要每次当我们要去调用一个接口时,都要去新建一个接口变量绑定对应的结构体实例化变量,再通过其调用接口。

不过需要注意的是,如果接口包含多个方法,那么结构体必须要为每个方法实现具体功能,不然会出现报错。我们试着添加向action接口中添加一个run()方法。

package mainimport "fmt"type action interface {walk(name string)run(name string)
}
type sinner struct {name string
}func setName(s *sinner, name string) sinner {s.name = namereturn *s
}
func (s *sinner) walk(name string) {fmt.Printf("%v is walking\n", s.name)
}
func walking(a action, name string) {a.walk(name)fmt.Printf("%T", a)
}
func main() {var (tmp sinner)setName(&tmp, "Ishmael")walking(&tmp, tmp.name)
}

运行结果为,可以看到会提示异常。

 # command-line-arguments
.\cpt.1.go:29:10: cannot use &tmp (value of type *sinner) as action value in argument to walking: *sinner does not implement action (missing method run)

编译完成,并显示退出代码 1
 

多态 

 同一结构体的不同实例化可以使用同一个接口,例子如下

package mainimport "fmt"type action interface {walk(name string)
}
type sinner struct {name string
}func setName(s *sinner, name string) sinner {s.name = namereturn *s
}
func (s *sinner) walk(name string) {fmt.Printf("%v is walking\n", s.name)
}
func walking(a action, name string) {a.walk(name)
}
func main() {var (ishmael sinnerfaust   sinner)setName(&ishmael, "Ishmael")setName(&faust, "Faust")walking(&ishmael, ishmael.name)walking(&faust, faust.name)
}

运行结果如下

Ishmael is walking
Faust is walking 

不同结构体的实例化也能调用同一接口。我们修改一下上面的代码,将setName方法也整合进接口,再新建一个结构enemy。例子如下

package mainimport "fmt"type action interface {walk(name string)setName(name string)
}
type sinner struct {name string
}
type enemy struct {name string
}func (s *sinner) walk(name string) {fmt.Printf("%v is walking\n", s.name)
}
func (s *sinner) setName(name string) {s.name = name
}
func (s *enemy) walk(name string) {fmt.Printf("%v is walking\n", s.name)
}
func (s *enemy) setName(name string) {s.name = name
}func setname(a action, name string) {a.setName(name)
}
func walking(a action, name string) {a.walk(name)
}
func main() {var (ishmael sinnerfaust   enemy)setname(&ishmael, "Ishmael")setname(&faust, "Faust")walking(&ishmael, ishmael.name)walking(&faust, faust.name)
}

运行结果如下

Ishmael is walking
Faust is walking 

接口嵌套 

接口可以嵌套另一个接口,通过接口嵌套,接口之间能形成简单的基础关系。但接口之间不具备方法重写功能,即多个接口嵌套组成一个新的接口,每个接口的方法都是唯一的。即不能出现下面这种情况--不同接口中定义了相同的方法名,但两个方法的返回值不一样。


type relationship interface {isMyWife(name string)int
}
type action interface {walk(name string)setName(name string)relationshipisMyWife(name string)string
}

把返回类型去掉或者改为同一种就行了,程序才能把两个不同接口里但定义相同的方法,当作一个方法去执行。

type relationship interface {isMyWife(name string) 
}
type action interface {walk(name string)setName(name string)relationshipisMyWife(name string) 
}

 综上,我们优化下程序可以得到一个嵌套了其他接口的接口,并通过函数的方式对其调用。

 

package mainimport "fmt"type relationship interface {relationship_isMyWife(name string)
}
type action interface {walk(name string)setName(name string)relationship
}
type sinner struct {name string
}func (s *sinner) walk(name string) {fmt.Printf("%v is walking\n", s.name)
}
func (s *sinner) setName(name string) {s.name = name
}
func (s *sinner) relationship_isMyWife(name string) {fmt.Printf("%v is my Wife!\n", s.name)
}
func getInterface(a action, name string) {a.setName(name)a.walk(name)a.relationship_isMyWife(name)
}
func main() {var (ishmael sinner)getInterface(&ishmael, "Ishmael")
}

运行结果如下

Ishmael is walking
Ishmael is my Wife!

相关文章:

GO语言--接口(interface)的定义及使用

接口定义 接口也是一种数据类型,它代表一组方法的集合。 接口是非侵入式的。即接口设计者无需知道接口被哪些类型实现,而接口使用者只需知道实现怎样的接口,并且无须指明实现哪一个接口。编译器在编译时就会知道哪个类型实现哪个接口&#…...

【Python语言基础】——Python MongoDB 查询

Python语言基础——Python MongoDB 查询 文章目录 Python语言基础——Python MongoDB 查询一、Python MongoDB 查询一、Python MongoDB 查询 筛选结果 在集合中查找文档时,您能够使用 query 对象过滤结果。 find() 方法的第一个参数是 query 对象,用于限定搜索。 实例 查找地…...

第十四届蓝桥杯模拟赛【第三期】Python

1 进制转换 问题描述   请找到一个大于 2022 的最小数,这个数转换成十六进制之后,所有的数位(不含前导 0)都为字母(A 到 F)。   请将这个数的十进制形式作为答案提交。 答案:2730 def ch…...

windows 下docker 安装clickhouse

docker 下载https://www.docker.com/products/docker-desktop/将下载下来的Docker Desktop Installer.exe文件双击进行安装即可,安装完成后,任务栏会出现一个蓝色的小鲸鱼图标(注意安装完成后可能会重启系统)Docker Desktop如果出…...

【华为OD机试真题 JAVA】TLV编码问题

标题:TLV编码问题 | 时间限制:1秒 | 内存限制:262144K | 语言限制:不限 TLV编码是按TagLengthValue格式进行编码的,一段码流中的信元用tag标识,tag在码流中唯一不重复,length表示信元value的长度,value表示信元的值,码流以某信元的tag开头,tag固定占一个字节,lengt…...

深度学习 Day26——使用Pytorch实现猴痘病识别

深度学习 Day26——使用Pytorch实现猴痘病识别 文章目录深度学习 Day26——使用Pytorch实现猴痘病识别一、前言二、我的环境三、前期工作1、设置GPU导入依赖项2、导入猴痘病数据集3、划分数据集四、构建CNN网络五、训练模型1、设置超参数2、编写训练函数3、编写测试函数4、正式…...

redis简单介绍

对于一名前端工程师,想要进阶成为全栈工程师,redis技术是我们一定需要掌握的。作为当前非关系型数据库Nosql中比较热门的key-value存储系统,了解redis的原理和开发是极其重要的。本文我会循序渐进的带领大家一步步认识redis,使用r…...

Understanding services:理解服务(Service)

文章目录背景1. 准备工作2. ros2 service list 命令3. ros2 service type 命令3.1 ros2 service list -t 命令4. ros2 service find 命令5. ros2 interface show 命令6. ros2 service call 命令参考官方文档: Understanding services背景 服务(Service&…...

【链表OJ题(五)】合并两个有序链表

​ ​📝个人主页:Sherry的成长之路 🏠学习社区:Sherry的成长之路(个人社区) 📖专栏链接:数据结构 🎯长路漫漫浩浩,万事皆有期待 文章目录链表OJ题(五)1. 合并…...

C++ Primer第五版_第三章习题答案(1~10)

文章目录练习3.1练习3.2一次读入一行一次读入一个词练习3.3练习3.4大的字符串长度大的字符串练习3.5未隔开的隔开的练习3.6练习3.7练习3.8练习3.9练习3.10练习3.1 使用恰当的using 声明重做 1.4.1节和2.6.2节的练习。 // 1.4.1 #include <iostream>using std::cin; using…...

小样本学习

机器学习就是从数据中学习&#xff0c;从而使完成任务的表现越来越好。小样本学习是具有有限监督数据的机器学习。类似的&#xff0c;其他的机器学习定义也都是在机器学习定义的基础上加上不同的限制条件衍生出来。例如&#xff0c;弱监督学习是强调在不完整、不准确、有噪声、…...

python打包成apk界面设计,python打包成安装文件

大家好&#xff0c;给大家分享一下如何将python程序打包成apk文件&#xff0c;很多人还不知道这一点。下面详细解释一下。现在让我们来看看&#xff01; 1、如何用python制作十分秒加减的apk 如何用python制作十分秒加减的apk&#xff1f;用法:. apk包放入apk文件目录,然后输入…...

pytorch转onnx踩坑日记

在深度学习模型部署时&#xff0c;从pytorch转换onnx的过程中&#xff0c;踩了一些坑。本文总结了这些踩坑记录&#xff0c;希望可以帮助其他人。 首先&#xff0c;简单说明一下pytorch转onnx的意义。在pytorch训练出一个深度学习模型后&#xff0c;需要在TensorRT或者openvin…...

极智AI | GPT4来了,ChatGPT又该升级了

欢迎关注我,获取我的更多经验分享 大家好,我是极智视界,本文介绍一下 GPT4来了,ChatGPT又该升级了,更多的是个人思考。 邀您加入我的知识星球「极智视界」,星球内有超多好玩的项目实战源码下载,链接:https://t.zsxq.com/0aiNxERDq 从 ChatGPT 发布 (2022年11月30日) 到…...

智能优化算法之灰狼优化算法(GWO)的实现(Python附源码)

文章目录一、灰狼优化算法的实现思路1、社会等级结构分级2、包围猎物3、攻击猎物4、搜索猎物二、算法步骤三、实例一、灰狼优化算法的实现思路 灰狼优化算法&#xff08;Grey Wolf Optimizer&#xff0c;简称GWO&#xff09;是由Seyedali Mirjalili等人于2014年提出的一种群智…...

leetCode热题10-15 解题代码,思路

前言 计划做一系列算法题的文章&#xff0c;因为自己这块确实比较薄弱&#xff0c;但又很重要&#xff01;写这篇文章前&#xff0c;我已经刷了一本剑指offer&#xff0c;leetcode top150道&#xff0c;牛客某题库106道 这个样子吧&#xff0c;感觉题量算是入门了吧&#xff1…...

同步辐射GISAXS和GIWAXS的原理及应用领域

同步辐射GISAXS和GIWAXS是两种常用的同步辐射X射线衍射技术&#xff0c;它们在材料科学、化学、生物学、物理学等领域中广泛应用。本文将从原理、实验方法和应用三个方面&#xff0c;对同步辐射GISAXS和GIWAXS进行描述和比较。 一、原理 GISAXS和GIWAXS都是利用X射线与样品相互…...

OpManager 进行网络性能管理

计算机网络构成了任何组织的 IT 基础架构的支柱。由于企业严重依赖基于互联网的应用程序&#xff0c;由于网络相关问题&#xff0c;最终用户不受影响非常重要。因此&#xff0c;借助网络管理解决方案监控和提高网络性能对于保持企业始终正常运行至关重要。这将确保维护服务级别…...

面试被问到向上转型和向下转型时,怎么回答?

目录 前置小知识 1、向上转型 补充&#xff1a;向上转型的三种情况 2、向下转型 使用关键字&#xff1a;instanceof 3、转型带来了什么好处 前置小知识 java中的继承&#xff0c;我们简单回顾一下 通过java中的继承机制&#xff0c;可以实现一个类继承另一个类&#xff…...

加密月解密:概述,基础篇

加密月解密&#xff1a;概述&#xff0c;基础篇 2022找工作是学历、能力和运气的超强结合体&#xff0c;遇到寒冬&#xff0c;大厂不招人&#xff0c;可能很多算法学生都得去找开发&#xff0c;测开 测开的话&#xff0c;你就得学数据库&#xff0c;sql&#xff0c;oracle&…...

地震勘探——干扰波识别、井中地震时距曲线特点

目录 干扰波识别反射波地震勘探的干扰波 井中地震时距曲线特点 干扰波识别 有效波&#xff1a;可以用来解决所提出的地质任务的波&#xff1b;干扰波&#xff1a;所有妨碍辨认、追踪有效波的其他波。 地震勘探中&#xff0c;有效波和干扰波是相对的。例如&#xff0c;在反射波…...

HBuilderX安装(uni-app和小程序开发)

下载HBuilderX 访问官方网站&#xff1a;https://www.dcloud.io/hbuilderx.html 根据您的操作系统选择合适版本&#xff1a; Windows版&#xff08;推荐下载标准版&#xff09; Windows系统安装步骤 运行安装程序&#xff1a; 双击下载的.exe安装文件 如果出现安全提示&…...

论文解读:交大港大上海AI Lab开源论文 | 宇树机器人多姿态起立控制强化学习框架(一)

宇树机器人多姿态起立控制强化学习框架论文解析 论文解读&#xff1a;交大&港大&上海AI Lab开源论文 | 宇树机器人多姿态起立控制强化学习框架&#xff08;一&#xff09; 论文解读&#xff1a;交大&港大&上海AI Lab开源论文 | 宇树机器人多姿态起立控制强化…...

代理篇12|深入理解 Vite中的Proxy接口代理配置

在前端开发中,常常会遇到 跨域请求接口 的情况。为了解决这个问题,Vite 和 Webpack 都提供了 proxy 代理功能,用于将本地开发请求转发到后端服务器。 什么是代理(proxy)? 代理是在开发过程中,前端项目通过开发服务器,将指定的请求“转发”到真实的后端服务器,从而绕…...

Hive 存储格式深度解析:从 TextFile 到 ORC,如何选对数据存储方案?

在大数据处理领域&#xff0c;Hive 作为 Hadoop 生态中重要的数据仓库工具&#xff0c;其存储格式的选择直接影响数据存储成本、查询效率和计算资源消耗。面对 TextFile、SequenceFile、Parquet、RCFile、ORC 等多种存储格式&#xff0c;很多开发者常常陷入选择困境。本文将从底…...

Mysql中select查询语句的执行过程

目录 1、介绍 1.1、组件介绍 1.2、Sql执行顺序 2、执行流程 2.1. 连接与认证 2.2. 查询缓存 2.3. 语法解析&#xff08;Parser&#xff09; 2.4、执行sql 1. 预处理&#xff08;Preprocessor&#xff09; 2. 查询优化器&#xff08;Optimizer&#xff09; 3. 执行器…...

站群服务器的应用场景都有哪些?

站群服务器主要是为了多个网站的托管和管理所设计的&#xff0c;可以通过集中管理和高效资源的分配&#xff0c;来支持多个独立的网站同时运行&#xff0c;让每一个网站都可以分配到独立的IP地址&#xff0c;避免出现IP关联的风险&#xff0c;用户还可以通过控制面板进行管理功…...

脑机新手指南(七):OpenBCI_GUI:从环境搭建到数据可视化(上)

一、OpenBCI_GUI 项目概述 &#xff08;一&#xff09;项目背景与目标 OpenBCI 是一个开源的脑电信号采集硬件平台&#xff0c;其配套的 OpenBCI_GUI 则是专为该硬件设计的图形化界面工具。对于研究人员、开发者和学生而言&#xff0c;首次接触 OpenBCI 设备时&#xff0c;往…...

淘宝扭蛋机小程序系统开发:打造互动性强的购物平台

淘宝扭蛋机小程序系统的开发&#xff0c;旨在打造一个互动性强的购物平台&#xff0c;让用户在购物的同时&#xff0c;能够享受到更多的乐趣和惊喜。 淘宝扭蛋机小程序系统拥有丰富的互动功能。用户可以通过虚拟摇杆操作扭蛋机&#xff0c;实现旋转、抽拉等动作&#xff0c;增…...

Linux安全加固:从攻防视角构建系统免疫

Linux安全加固:从攻防视角构建系统免疫 构建坚不可摧的数字堡垒 引言:攻防对抗的新纪元 在日益复杂的网络威胁环境中,Linux系统安全已从被动防御转向主动免疫。2023年全球网络安全报告显示,高级持续性威胁(APT)攻击同比增长65%,平均入侵停留时间缩短至48小时。本章将从…...