购物商城网站建设公司/公司网站制作要多少钱
GO系列
1、GO学习之Hello World
2、GO学习之入门语法
3、GO学习之切片操作
4、GO学习之 Map 操作
5、GO学习之 结构体 操作
6、GO学习之 通道(Channel)
7、GO学习之 多线程(goroutine)
8、GO学习之 函数(Function)
9、GO学习之 接口(Interface)
文章目录
- GO系列
- 前言
- 一、什么是接口(interface)?
- 二、如何定义接口
- 三、如何实现接口
- 3.1 多个类型实现同一接口
- 3.2 一个类型实现多个接口
- 3.3 接口嵌套
- 3.4 空接口
- 四、接口与类型断言
- 五、接口运用
- 六、总结
前言
按照公司目前的任务,go 学习是必经之路了,虽然行业卷,不过技多不压身,依旧努力!!!
在JAVA
中我们可以使用interface
来定义一个接口,抽离出来公共的字段和方法,再有不同的class
来实现这些接口和接口中方法,来实现代码的解耦和灵魂,主要依据的就是JAVA
的多态性,比如说在 Spring
框架中,有 EventListener
接口,然后实现了此接口的有好多class
(ContextRefreshListener、RestartListener…),每个实现类都有个子不同的功能。
那在 Go 语言中也有 interface
,我们可以通过 interface
来定义一种对象的行为规范,也就是定义了一组行为,不需要关注这些规范如何实现,我们可以通过接口将代码解耦,使得不同模块之间依赖减少,提高代码可维护性。
一、什么是接口(interface)?
- interface 是一种类型,描述了对象的行为但是不关心实现
- interface 只定义了方法,没有实现,有其他类型实现,是一组方法的集合
- 接口提供了一种约定,告诉其他类型实现这些方法即可满足接口的要求
- 不像其他语言中的接一样需要显式地声明实现了哪些接口,Go 语言中的实现是隐式的,只要一个类型实现了接口中定义的所有方法,就视为该类型实现了接口
二、如何定义接口
- 接口的定义语法:
type {interfaceName} interface { MethodName(paramName paramType) returnType }
,比如:type Runner interface{ run(name string) string }
- 接口中的方法只有方法名、参数列表和返回值类型,没有方法体
- 接口中方法的参数和返回值可以是任何类型,包括 interface 类型(强调:interface 是一种类型)
- 接口中方法可以有多个返回值,比如:
type Shape interface {Area() (float64, error)}
- 接口定义中方法名称和参数列表组成了接口的签名
三、如何实现接口
- 如果一个类型实现了接口中定义的所有方法,就视为该类型实现了接口
- 如果一个类型实现了某个接口,那么可以将该类型的实现赋值给接口类型变量
- 一个类可以实现多个接口
3.1 多个类型实现同一接口
此例子中,定义了一个 Shape 的接口,这个接口提供了
Area
方法用来求图形的面积,分别定义矩形(Rectangle)和 圆形(Circle)两个结构体,并且实现了 Shape 中的 Area 方法,初始化矩形和圆形并且调用 Area 方法求出面积。
package mainimport "fmt"// 定义一个图形接口,方法是求图形的面积
type Shape interface {Area() float64
}// 定义一个矩形
type Rectangle struct {Width float64Height float64
}// 矩形实现了 Shape 接口中求面积的 Area 方法
func (r Rectangle) Area() float64 {return r.Width * r.Height
}// 定义一个圆形
type Circle struct {Radius float64
}// 圆形实现了 Shape 接口中求面积的 Area 方法
func (c Circle) Area() float64 {return 3.14 * c.Radius * c.Radius
}func main() {// 定义一个接口类型变量var shape Shape// 创建一个矩形并赋值给接口 shapeshape = Rectangle{Width: 5, Height: 10}fmt.Printf("矩形的面积是:%+v\n", shape.Area())// 创建一个圆形并赋值给接口 shapeshape = Circle{Radius: 3}fmt.Printf("圆形的面积是:%+v\n", shape.Area())
}
运行结果:
PS D:\workspaceGo\src\interface> go run .\interfaceTest.go
矩形的面积是:50
圆形的面积是:28.259999999999998
3.2 一个类型实现多个接口
此例子中,定义了两个接口,分别是 ShapeArea(求面积) 和 ShapeRound(求周长) 两个接口,实例化了 Sequre 类型并且赋值给两个接口,调用各自接口方法
package mainimport "fmt"// 定义一个图形接口,方法是求图形的面积
type ShapeArea interface {Area() float64
}// 定一个图形接口,方法是求图形周长
type ShageRound interface {Round() float64
}// 定义一个正方形
type Sequre struct {Side float64
}// 正方形实现了 ShapeArea 接口中求面积的 Area 方法
func (s Sequre) Area() float64 {return s.Side * s.Side
}// 正方形实现了 ShapeRound 接口中周长 Round 的方法
func (s Sequre) Round() float64 {return 4 * s.Side
}func main() {// 定义接口var spaceArea ShapeAreavar spaceRound ShageRound// 实例化 Sequre 结构体s := Sequre{Side: 9}// 赋值给接口 spaceArea 以求面积spaceArea = sfmt.Printf("正方形的面积是:%+v\n", spaceArea.Area())// 赋值给接口 spaceRound 以求周长spaceRound = sfmt.Printf("正方形的周长是:%+v\n", spaceRound.Round())
}
运行结果:
PS D:\workspaceGo\src\interface> go run .\interfaceTest2.go
正方形的面积是:81
正方形的周长是:36
3.3 接口嵌套
此示例中,定义了两个接口 Sayer 和 Mover ,为了方便其他类型是,又定义了一个接口 Animal 嵌套了 Sayer 和 Mover 两个接口,基于两个接口的规则一自身,然后定义了 Cat 结构体类型,实例化之后赋值给了 Animal 变量 ‘yuanbao’,元宝是之前养过的一只很有灵性的黑白猫,元宝就可以叫,还可以上蹿下跳了。
package mainimport "fmt"// 定义接口 表示可以说话
type Sayer interface {say()
}// 定义接口,表示可以移动
type Mover interface {move()
}// 接口嵌套
type Animal interface {SayerMover
}// 定义结构体类型 猫咪
type Cat struct {Name string
}// 定义猫咪叫的方法
func (c Cat) say() {fmt.Printf("喵咪 %+v 在叫'喵喵喵'\n", c.Name)
}// 定义猫咪动的方法
func (c Cat) move() {fmt.Printf("猫咪 %+v 在上蹿下跳\n", c.Name)
}func main() {var yuanbao Animalyuanbao = Cat{Name: "元宝"}yuanbao.say()yuanbao.move()
}
运行结果:
PS D:\workspaceGo\src\interface> go run .\interfaceNested.go
喵咪 元宝 在叫'喵喵喵'
猫咪 元宝 在上蹿下跳
3.4 空接口
此示例中定义了一个空接口,既然接口是一种类型,不关心实现,那我们可以借助空接口来实现接受任何类型参数,类似于
JAVA
中的Object
超类,可以接受任何参数,可以作为函数的参数,也可以放在 map 中以便此 map 存放任何类型的值。
package mainimport "fmt"// 定义一个空接口
type Object interface{}// 定义一个函数,接受任何类型参数
func show(o interface{}) {fmt.Printf("type: %T, value: %+v\n", o, o)
}func main() {show(100)show("phan日复一日,刻苦学习,成就大业!")// 定义一个 Map, key为字符串,值为任何类型var myInfo = make(map[string]interface{})myInfo["name"] = "phen"myInfo["age"] = 25myInfo["hobby"] = "运动,看书,数钱"myInfo["rich"] = falsefmt.Printf("phen的个人信息:%+v\n", myInfo)
}
运行结果:
PS D:\workspaceGo\src\interface> go run .\interfaceEmpty.go
type: int, value: 100
type: string, value: phan日复一日,刻苦学习,成就大业!
phen的个人信息:map[age:25 hobby:运动,看书,数钱 name:phen rich:false]
四、接口与类型断言
- 类型断言是将接口类型转换为其他类型的操作
- 类型断言有两种方式:1、
value, ok := x.(T)
,2、value := x.(T)
- 类型断言可以判断接口类型是否实现了某个接口
- 类型断言可以判断接口类型是否是某个具体类型
package mainimport "fmt"// 定义一个图形接口,方法是求图形的面积
type Shape interface {Area() float64
}// 定义一个矩形
type Rectangle struct {Width float64Height float64
}// 矩形实现了 Shape 接口中求面积的 Area 方法
func (r Rectangle) Area() float64 {return r.Width * r.Height
}func main() {// 定义一个接口类型变量var shape Shape// 接口断言,如果 ok = true, 则 rect 的类型为 Rectangleif rect, ok := shape.(Rectangle); ok {fmt.Printf("矩形的面积为 %+v\n", rect.Area())} else {fmt.Println("接口 shape 不包含 Rectangle 的值")}// 创建一个矩形并赋值给接口 shapeshape = Rectangle{Width: 5, Height: 10}// 接口断言,如果 ok2 = true, 则 r 的类型为 Rectangleif r, ok2 := shape.(Rectangle); ok2 {fmt.Printf("矩形的面积是:%+v\n", r.Area())} else {fmt.Println("接口 shape 不包含 Rectangle 的值")}
}
运行结果:
PS D:\workspaceGo\src\interface> go run .\interfaceTest.go
接口 shape 不包含 Rectangle 的值
矩形的面积是:50
从运行结果看,在没有给接口 shape 赋值的时,断言 ok 是 false,下面给接口类型变量 shape 正式赋值了,则成功执行了 r.Area() 计算了面积。
五、接口运用
- 接口类型可以作为函数的参数接受参数
- 接口类型可以是任意类型作为 map、结构体等的 value
- 接口类型可以让代码解耦
- 利用接口可以进行提取和抽离出来公共模块,提高开发效率
- 等…
六、总结
接口类型在 Go 语言中是非常重要的特性,它提供了一种约定和抽象的方式,让不同的类型可以用相同的方式处理。在实际开发中有许多用途和场景,重要包括:
- 实现多态性:让不同类型以相同方式处理,提高代码的灵活性和复用性
- 解耦代码:通过接口将代码解耦,使得不同模块直接依赖较少,从而提高代码的可维护性
- 实现设计模式:接口类型可以很好的支持如 工厂模式、策略模式等这些模式的实现,让代码更加简洁易于维护和理解
- 扩展性和适配器模式:通过接口,可以很好的扩展程序的功能,只需实现相应的方法即可,同时接口也可以适用于不同的模块,将不同的类型适配成统一的接口类型,实现代码的复用和扩展
- 测试和模拟:在单元测试中,可以利用接口来模拟依赖项,实现代码的测试隔离。通过使用接口,可以方便的替换真实的依赖实现,从而实现对代码的独立测试
总而言之,接口类型在 Go 语言中非常灵活和强大,它可以帮助我们实现面向接口编程,提高代码的灵活性和可复用性,减少代码的耦合性,使得代码更加清晰、简洁和易于维护。在实际开发中,合理地使用接口类型,可以使代码更加健壮和可扩展,提高开发效率和质量。
现阶段还是对 Go 语言的学习阶段,想必有一些地方考虑的不全面,本文示例全部是亲自手敲代码并且执行通过。
如有问题,还请指教。
评论去告诉我哦!!!一起学习一起进步!!!
相关文章:

GO学习之 接口(Interface)
GO系列 1、GO学习之Hello World 2、GO学习之入门语法 3、GO学习之切片操作 4、GO学习之 Map 操作 5、GO学习之 结构体 操作 6、GO学习之 通道(Channel) 7、GO学习之 多线程(goroutine) 8、GO学习之 函数(Function) 9、GO学习之 接口(Interface) 文章目录 GO系列前言一、什么是…...

ansible常见模块的运用
ansible常见模块的运用 一:Ansible简介二:ansible 环境安装部署管理端安装 ansibleansible 目录结构配置主机清单配置密钥对验证 三:ansible 命令行模块1.command 模块在远程主机执行命令,不支持管道,重定向…...

合宙Air724UG LuatOS-Air script lib API--patch
patch Table of Contents patch patch.safeJsonDecode(s) (local函数 无法被外部调用) patch 模块功能:Lua补丁 patch.safeJsonDecode(s) (local函数 无法被外部调用) 封装自定义的json.decode接口 参数 名称 传入值类型 释义 s string json格式的字符串 返回值 t…...

pytorch求导
pytorch求导的初步认识 requires_grad tensor(data, dtypeNone, deviceNone, requires_gradFalse)requires_grad是torch.tensor类的一个属性。如果设置为True,它会告诉PyTorch跟踪对该张量的操作,允许在反向传播期间计算梯度。 x.requires_grad 判…...

Java基础异常详解
Java基础异常详解 文章目录 Java基础异常详解编译时异常(Checked Exception):运行时异常(Unchecked Exception): Java中的异常是用于处理程序运行时出现的错误或异常情况的一种机制。 异常本身也是一个类。 异常分为…...

vue3+vue-i18n 监听语言的切换
最近在用 vue3 做一个后台管理系统,之前是只考虑中文,现在加了个需求是多语言。 本来也不是太难的需求,但是我用的并不熟悉,并且除了页面展示不同的语言,需求是在切换语言的时候在几个页面中需要做出一些自定义的行为&…...

【考研复习】24王道数据结构课后习题代码|2.3线性表的链式表示
文章目录 总结01 递归删除结点02 删除结点03 反向输出04 删除最小值05 逆置06 链表递增排序07 删除区间值08 找公共结点09 增序输出链表10 拆分链表--尾插11 拆分链表--头插12 删除相同元素13 合并链表14 生成含有公共元素的链表C15 求并集16 判断子序列17 判断循环链表是否对称…...

娇滴滴的一朵花(Python实现)
目录 1 娇滴滴的她 2 Python代码实现 1 娇滴滴的她 娇滴滴。双眉敛破春山色。春山色。 为君含笑,为君愁蹙。多情别後无消息。 此时更有谁知得。谁知得。夜深无寐,度江横笛。 2 Python代码实现 import turtle from turtle import * turtle.title(春天送她一朵小花)…...

Android AccessibilityService研究
AccessibilityService流程分析 AccessibilityService开启方式AccessibilityService 开启原理 AccessibilityService开启方式 . 在Framework里直接添加对应用app 服务component。 loadSetting(stmt, Settings.Secure.ACCESSIBILITY_ENABLED,1); loadSetting(stmt, Settings.Se…...

华为OD机试(含B卷)真题2023 算法分类版,58道20个算法分类,如果距离机考时间不多了,就看这个吧,稳稳的
目录 一、数据结构1、线性表2、优先队列3、滑动窗口4、二叉树5、并查集6、栈 二、算法1、基础算法2、字符串3、图4、动态规划5、数学 三、漫画算法2:小灰的算法进阶参与方式 很多小伙伴问我,华为OD机试算法题太多了,知识点繁杂,如…...

JMeter命令行执行+生成HTML报告
1、为什么用命令行模式 使用GUI方式启动jmeter,运行线程较多的测试时,会造成内存和CPU的大量消耗,导致客户机卡死; 所以一般采用的方式是在GUI模式下调整测试脚本,再用命令行模式执行; 命令行方式支持在…...

学习Boost二:从附录3来看编码习惯
附录C 关键字浅谈 在C11标准中(C11.2.12)总共定义了73个关键字(keyword)、2个“准”关键字(identifiers with special meaning)和11个操作符替代字(alternative representation)[1]。…...

STM32基础入门学习笔记:核心板 电路原理与驱动编程
文章目录: 一:LED灯操作 1.LED灯的点亮和熄灭 延迟闪烁 main.c led.c led.h BitAction枚举 2.LED呼吸灯(灯的强弱交替变化) main.c delay.c 3.按键控制LED灯 key.h key.c main.c 二:FLASH读写程序(有…...

最后一次模拟考试题解
哦我想这不用看都知道是为了水任务 T1 黑白染色 其实这题有原 什么手写体 md (指 markdown) 分析 首先这题如果你题目没看错的话 ,会发现其实他是 n m n \times m nm 让你求 n n n \times n nn 的区域内的点(不会只有我一个人题目看错了罢 然后我们会发现…...

Mac 创建和删除 Automator 工作流程,设置 Terminal 快捷键
1. 创建 Automator 流程 本文以创建一个快捷键启动 Terminal 的自动操作为示例。 点击打开 自动操作; 点击 新建文稿 点击 快速操作 选择 运行 AppleScript 填入以下内容 保存名为 “Open Terminal” 打开 设置 > 键盘,选择 键盘快捷键 以此选择 服…...

2023华为OD机试真题B卷 Java 实现【最长的元音串】
前言 本题使用Java解答,如果需要Python代码,链接 题目 给定一个只由英文字母(a-z, A-Z)组成的字符串,找出其中最长的只包含元音字母(a, e, i, o, u, A, E, I, O, U)的子串,并返回其长度。如果不存在元音子串,则返回0。 输入: 一个由英文字母组成的字符串,长度大…...

网络防御之传输安全
1.什么是数据认证,有什么作用,有哪些实现的技术手段? 数据认证是一种权威的电子文档 作用:它能保证数据的完整性、可靠性、真实性 技术手段有数字签名、加密算法、哈希函数等 2.什么是身份认证,有什么作用,有哪些…...

【css】组合器
组合器是解释选择器之间关系的某种机制。在简单选择器器之间,可以包含一个组合器,从而实现简单选择器难以达到的效果。 CSS 中有四种组合器: 后代选择器 (空格):匹配属于指定元素后代的所有元素,示例:div …...

HTTPS、TLS加密传输
HTTPS、TLS加密传输 HTTPS、TLS加密传输1、HTTPS(HyperText Transfer Protocol Secure)2、TLS HTTPS、TLS加密传输 1、HTTPS(HyperText Transfer Protocol Secure) HTTPS(HyperText Transfer Protocol Secure&#x…...

docker frp 搭建 http + stcp 代理
所需服务器 2台 一台具有国外公网ip 一台具有国内 ip 内网外网都可以 外公网ip服务器配置如下 cat docker-compose.yamlversion: "2" services:frps:image: alpine:latesthostname: frpsrestart: alwayscontainer_name: frpsprivileged: trueuser: rootcommand: […...

项目出bug,找不到bug,如何拉回之前的版本
1.用gitee如何拉取代码 本文为转载于「闪耀太阳a」的原创文章原文链接:https://blog.csdn.net/Gufang617/article/details/119929145 怎么从gitee上拉取代码 1.首先找到gitee上想要拉取得代码URL地址 点击复制这里的https地址 1 ps:(另外一种方法&…...

vue-cli
vue-cli脚手架 案例一: 案例二: 案例三: 一、脚手架简介 Vue脚手架是Vue官方提供的标准化开发工具(开发平台),它提供命令行和UI界面,方便创建vue工程、配置第三方依赖、编译vue工程 1. …...

android获取屏幕分辨率的正确方法;获取到分辨率(垂直方向像素)的不正确
我通过下面的方法去获取屏幕分辨率的,但获取到的分辨率有时会不准确。原因是此方法有时候会忽略一些布局或控件的高度,从而得不到正确的高度。 public static String getDeviceResolution(Context context){//从系统服务中获取窗口管理器WindowManager w…...

机器学习笔记之优化算法(八)简单认识Wolfe Condition的收敛性证明
机器学习笔记之优化算法——简单认识Wolfe Condition收敛性证明 引言回顾: Wolfe \text{Wolfe} Wolfe准则准备工作推导条件介绍推导结论介绍 关于 Wolfe \text{Wolfe} Wolfe准则收敛性证明的推导过程 引言 上一节介绍了非精确搜索方法—— Wolfe \text{Wolfe} Wolf…...

通过win+r安装jupyter报错
通过pip install jupyter安装jupyter报错处理办法 1、python 更新到最新版,最好多执行几次后在安装jupyter python.exe -m pip install --upgrade pip 2、通过镜像安装 pip install jupyter --force-reinstall pip -i http://pypi.douban.com/simple/ --trusted-h…...

C#声明一个带返回值的委托
1、声明 public delegate string TestDel(string str); 2、使用 TestDel t; t (string str) > str; t (string str) > str "1"; t (string str) > str "2"; t (string str) > str "3"; Console.WriteLine(t ("hhhh&qu…...

Flutter 自定义view
带进度动画的圆环。没gif,效果大家自行脑补。 继承CustomPainter,paint()方法中拿到canvas,绘制API和android差不多。 import package:flutter/material.dart;class ProgressRingPainter extends CustomPainter {double strokeWidth 20;Col…...

Ubuntu新装系统报错:sudo: vim:找不到命令
问题: 新安装的老版本Ubuntu系统,发现在使用vim命令的时候报错: sudo:vim:找不到命令 解决办法 这是因为没有安装vim,直接运行下面命令安装vim sudo apt-get install vim...

Vue3自定义简单的Swiper滑动组件-触控板滑动鼠标滑动左右箭头滑动-demo
代码实现了一个基本的滑动功能,通过鼠标按下、鼠标松开和鼠标移动事件来监听滑动操作。 具体实现逻辑如下: 在 onMounted 钩子函数中,我们为滚动容器添加了三个事件监听器:mousedown 事件:当鼠标按下时,设置…...

三个主流数据库(Oracle、MySQL和SQL Server)的“单表造数
oracle 1.创建表 CREATE TABLE "YZH2_ORACLE" ("VARCHAR2_COLUMN" VARCHAR2(20) NOT NULL ENABLE,"NUMBER_COLUMN" NUMBER,"DATE_COLUMN" DATE,"CLOB_COLUMN" CLOB,"BLOB_COLUMN" BLOB,"BINARY_DOUBLE_COLU…...