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

golang接口-interface

interface接口

概述

接口(interface)是 Go 语言中的一种类型,用于定义行为的集合,它通过描述类型必须实现的方法,规定了类型的行为契约。

它把所有的具有共性的方法定义在一起,任何其他类型只要实现了这些方法就是实现了这个接口。

隐性实现

1.Go 中没有关键字显式声明某个类型实现了某个接口。
2.只要一个类型实现了接口要求的所有方法,该类型就自动被认为实现了该接口。

实现接口的作用

如果A类型实现了B接口,由于接口也是类型,我们就可以声明B接口类型的变量来使用A类型的相关特性。

//传统变量的声明和使用
var 变量名 类型A = 类型A的值//类型A实现了接口B后
/*在实际编译过后,该变量就是类型A的变量
*/
var 变量名 类型B = 类型A的值
//类型C实现了接口B后
var 变量名 类型B = 类型C的值

接口的定义

接口定义使用关键字 interface,其中包含方法声明。

基本语法

type 接口类型名 interface{//参数签名方法名1(参数类型列表) 返回值类型方法名2(参数类型列表) 返回值类型...
}

接口定义举例

type Animaler interface{GetName() string GetAge() int
}

命名规范

  • 使用type将接口定义为自定义的类型名。Go语言的接口在命名时,一般会在单词后面添加er,如有写操作的接口叫Writer,有字符串功能的接口叫Stringer等。接口名最好要能突出该接口的类型含义。
  • 当方法名首字母是大写且这个接口类型名首字母也是大写时,这个方法可以被接口所在的包(package)之外的代码访问。
  • 参数列表和返回值列表中的参数变量名可以省略

接口的实现

一个实例对象只要全部实现了接口中的方法,那么就实现了这个接口。换句话说,接口就是一个需要实现的方法列表

也可以理解为任意类型,只要他具备接口中的所有方法,那么该类型的实例就实现了接口。

举例

package interface_knowledgeimport "fmt"type Animaler interface{GetName() string GetAge() int
}type Dog struct{name stringage int 
}func (d Dog) GetAge() int{return d.age
}func (d Dog) GetName() string{return d.name
}func (d Dog) Say(){fmt.Println("wang")
}

由于Dog结构体类型具备了接口Animal中的所有方法,所以Dog结构体实现了Animal接口。

指针类型方法

使用了指针类型接收者

如果我们实现接口时使用了指针类型接收者,则接口只能接收指针类型。

package interface_knowledgeimport "fmt"type Personer interface{GetAge() intGetName() string
}type Student struct{name string age int
}func (s *Student) GetAge() int{return s.age
}func (s Student) GetName() string{return s.name
}func GetPersonVal(){var person Personer/*只要在实现接口的过程中使用了指针类型的接收者则接口只能接收对应指针类型的变量*//*报错:cannot use Student{} (value of type Student) as Personer value in assignment: Student does not implement Personer (method GetAge has pointer receiver)*/// person = Student{}//正确person = &Student{}fmt.Printf("接口实例的值为%#v\n",person)
}

运行结果

接口实例的值为&interface_knowledge.Student{name:"", age:0}
没有使用指针类型接收者

如果没有使用指针类型接收者,则指针与非指针都可以。

package interface_knowledgeimport "fmt"type Personer interface{GetAge() intGetName() string
}type Work struct{salary int name string age int 
}func (w Work) GetAge() int{return w.age
}func (w Work) GetName() string{return w.name
}func GetWorkVal(){var person Personerperson = Work{}fmt.Printf("接口实例的值为%#v\n",person)person = &Work{}fmt.Printf("接口实例的值为%#v\n",person)
}

运行结果

接口实例的值为interface_knowledge.Work{salary:0, name:"", age:0}
接口实例的值为&interface_knowledge.Work{salary:0, name:"", age:0}

接口的性质

接口本身就是一个动态类型,我们可以声明该类型的变量。

动态类型

如果一个类型A实现了接口B。那么接口B类型的变量X就可以接收A类型的值,编译过程中变量X的类型就是A。

举例

package interface_knowledgeimport "fmt"type Animaler interface{GetName() string GetAge() int
}type Dog struct{name stringage int 
}func (d Dog) GetAge() int{return d.age
}func (d Dog) GetName() string{d.name = "yellow"return d.name
}type Cat struct{NickName stringage int weight int
}func (c Cat) GetAge() int{return c.age
}func (c Cat) GetName() string{c.NickName = "kitty"return c.NickName
}/*Dog和Cat都实现了接口Animaler
*/
func GetVal(){//此时变量anl的实际类型就是Catvar anl Animaler = Cat{NickName: "kitty",age:25,weight: 255}//此时变量myDog的实际类型就是Dogvar myDog Animaler = Dog{name:"yellow",age: 30}fmt.Printf("anl的值为%#v\n",anl)fmt.Printf("myDog的值为%#v\n",myDog)
}

结果

anl的值为interface_knowledge.Cat{NickName:"kitty", age:25, weight:255}
myDog的值为interface_knowledge.Dog{name:"yellow", age:30}

所以接口类型的变量的运行时类型与运行时值都是由赋值动态决定的,所以又叫做动态类型和动态值。

区别

func GetVal(){//此时变量anl的实际类型就是Catvar anl Animaler = Cat{NickName: "kitty",age:25,weight: 255}//此时变量myDog的实际类型就是Dogvar myDog Animaler = Dog{name:"yellow",age: 30}fmt.Printf("anl的值为%#v\n",anl)fmt.Printf("myDog的值为%#v\n",myDog)anl = Dog{name:"happy",age:20}fmt.Printf("anl的值为%#v\n",anl)
}

结果

anl的值为interface_knowledge.Cat{NickName:"kitty", age:25, weight:255}
myDog的值为interface_knowledge.Dog{name:"yellow", age:30}
anl的值为interface_knowledge.Dog{name:"happy", age:20}

由此可以知道anl的底层类型仍然是Animaler,并没有因为赋值改变,所以他可以接收不同类型的值。

接口的零值

接口是个引用类型,在接口没有接受赋值时,接口类型变量的值为nil.

举例

package interface_knowledge
import "fmt"
type Animaler interface{GetName() string GetAge() int
}
//接口的零值
func GetZero(){var zero Animalerfmt.Printf("接口类型变量的零值为%#v\n",zero)
}

结果

接口类型变量的零值为<nil>

注意

接口类型的零值虽然是nil,但是此时已经分配了内存,所以可以直接赋值。

package interface_knowledgeimport "fmt"type Animaler interface{GetName() string GetAge() int
}type Cat struct{NickName stringage int weight int
}func (c Cat) GetAge() int{return c.age
}func (c Cat) GetName() string{c.NickName = "kitty"return c.NickName
}//接口的零值
func GetZero(){var zero Animalerfmt.Printf("接口类型变量的零值为%#v\n",zero)//给零值接口赋值zero = Cat{}fmt.Printf("赋值后变量的值为%#v\n",zero)
}

调用结果

接口类型变量的零值为<nil>
赋值后变量的值为interface_knowledge.Cat{NickName:"", age:0, weight:0}

接口的用法1–多态

应用场景

目前有如下代码:

type Dog struct{name string
}type Cat struct{name string
}//获得狗的名字
func GetNameDog(d Dog)string{return d.name
}//获取猫的名字
func GetNameCat(c Cat)string{return d.name
}

这两个获取名字的方法相似度极高,我们想把他合并成一个方法,

func GetName(c Type) string{return c.name
}

但是由于DogCat是不同的类型,所以让传参出现了困难。

//传参
var dog Dog
GetNameDog(dog)var Cat cat
GetNameCat(cat)

此时我们就可以用接口来解决这个问题。

实现接口

package interface_knowledgeimport "fmt"type Animaler interface{GetName() string GetAge() int
}type Dog struct{name stringage int 
}func (d Dog) GetAge() int{return d.age
}func (d Dog) GetName() string{d.name = "yellow"return d.name
}type Cat struct{NickName stringage int weight int
}func (c Cat) GetAge() int{return c.age
}func (c Cat) GetName() string{c.NickName = "kitty"return c.NickName
}

DogCat都实现了接口Animaler,则我们可以用Animaler类型来接收DogCat类型,即

func GetName(a Animaler) string{return a.GetName()
}

调用

package mainimport ("fmt""go_learn/interface_knowledge"
)func main(){var dog interface_knowledge.Dogstr :=interface_knowledge.GetName(dog)fmt.Printf("狗的名字为%#v\n",str)var cat interface_knowledge.Catstr1 := interface_knowledge.GetName(cat)fmt.Printf("猫的名字为%#v\n",str1)
}

结果

狗的名字为"yellow"
猫的名字为"kitty"

由此我们就实现了用一个接口类型参数接收两个不同类型的其他参数。

相关文章:

golang接口-interface

interface接口 概述 接口&#xff08;interface&#xff09;是 Go 语言中的一种类型&#xff0c;用于定义行为的集合&#xff0c;它通过描述类型必须实现的方法&#xff0c;规定了类型的行为契约。 它把所有的具有共性的方法定义在一起&#xff0c;任何其他类型只要实现了这…...

Epub转PDF软件Calibre电子书管理软件

Epub转PDF软件&#xff1a;Calibre电子书管理软件 https://download.csdn.net/download/hu5566798/90549599 一款好用的电子书管理软件&#xff0c;可快速导入电脑里的电子书并进行管理&#xff0c;支持多种格式&#xff0c;阅读起来非常方便。同时也有电子书格式转换功能。 …...

【自学笔记】PHP语言基础知识点总览-持续更新

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 文章目录 1. PHP 简介2. PHP 环境搭建3. 基本语法变量与常量数据类型运算符 4. 控制结构条件语句循环语句 5. 函数函数定义与调用作用域 6. 数组7. 字符串8. 表单处理9. 会话…...

FAST-LIVO2 Fast, Direct LiDAR-Inertial-Visual Odometry论文阅读

FAST-LIVO2 Fast, Direct LiDAR-Inertial-Visual Odometry论文阅读 论文下载论文翻译FAST-LIVO2: 快速、直接的LiDAR-惯性-视觉里程计摘要I 引言II 相关工作_直接方法__LiDAR-视觉&#xff08;-惯性&#xff09;SLAM_ III 系统概述IV 具有顺序状态更新的误差状态迭代卡尔曼滤波…...

【Git】--- Git远程操作 标签管理

Welcome to 9ilks Code World (๑•́ ₃ •̀๑) 个人主页: 9ilk (๑•́ ₃ •̀๑) 文章专栏&#xff1a; Git 前面我们学习的操作都是在本地仓库进行了&#xff0c;如果团队内多人协作都在本地仓库操作是不行的&#xff0c;此时需要新的解决方案 --- 远程仓库。…...

Docker学习之服务编排(day9)

文章目录 前言一、问题描述二、解决方案1.安装Docker Compose1.1 [github下载相应版本](https://github.com/docker/compose/releases)1.2 将下载的文件移动到 /usr/local/bin 目录&#xff0c;确保它能够被系统识别为可执行文件1.3 赋予执行权限1.4 验证安装1.5 创建软链 2. 使…...

前后端常见模型以及相关环境配置介绍

一、前端常见框架 Vue.js 特点&#xff1a;采用数据驱动的响应式编程&#xff0c;组件化的开发模式使得代码结构清晰&#xff0c;易于维护&#xff0c;且学习成本相对较低&#xff0c;适合初学者和快速迭代的项目。应用场景&#xff1a;广泛应用于各类 Web 应用开发&#xff…...

职能型组织、项目型组织、矩阵型组织的介绍及优缺点比较

PMP考试中&#xff0c;经常会涉及到职能型组织、项目型组织、矩阵型组织的比较&#xff0c;下面简单介绍下职能型组织、项目型组织、矩阵型组织及其优缺点&#xff1a; 一、职能型组织 定义&#xff1a;以专业职能划分部门&#xff08;如财务、技术、市场等&#xff09;&…...

Java基本类型深度解析:从内存模型到高效编程实践

Java基本类型深度解析&#xff1a;从内存模型到高效编程实践 一、Java基本类型概述 Java作为强类型语言&#xff0c;定义了8种基本数据类型&#xff08;Primitive Types&#xff09;&#xff0c;这些类型直接存储数据值而非对象引用&#xff0c;是构建Java程序的基础。它们的…...

论文阅读笔记——ST-4DGS,WideRange4D

ST-4DGS ST-4DGS 论文 在 4DGS 中&#xff0c;变形场 F \mathcal{F} F 与运动参数 X 和形状参数 ( S , R ) (S,R) (S,R) 高度耦合&#xff0c;导致训练时高斯表示紧凑型退化&#xff0c;影响动态渲染质量。由此&#xff0c;本文提出两种方法解耦运动与形状参数&#xff0c;保…...

[python]基于yolov8实现热力图可视化支持图像视频和摄像头检测

YOLOv8 Grad-CAM 可视化工具 本工具基于YOLOv8模型&#xff0c;结合Grad-CAM技术实现目标检测的可视化分析&#xff0c;支持图像、视频和实时摄像头处理。 功能特性 支持多种Grad-CAM方法实时摄像头处理视频文件处理图像文件处理调用简单 环境要求 Python 3.8需要电脑带有…...

五.ubuntu20.04 - ffmpeg推拉流以及Nginx、SRS本地部署

一.本地部署nginx 1.编译ffmpeg&#xff0c;参考这位博主的&#xff0c;编译选项有的enable找不到的不需要的可以直接删除&#xff0c;但是像sdl&#xff08;包含ffplay&#xff09;、h264、h265这些需要提前下载好&#xff0c;里面都有下载指令。 Ubuntu20.04 编译安装 FFmp…...

深度神经网络全解析:原理、结构与方法对比

深度神经网络全解析&#xff1a;原理、结构与方法对比 1. 引言 随着人工智能的发展&#xff0c;深度神经网络&#xff08;Deep Neural Network&#xff0c;DNN&#xff09;已经成为图像识别、自然语言处理、语音识别、自动驾驶等领域的核心技术。相比传统机器学习方法&#x…...

豪越科技消防一体化平台:打通消防管理“任督二脉”

在城市的车水马龙间&#xff0c;火灾隐患如潜藏的暗礁&#xff0c;威胁着人们的生命财产安全。传统消防管理模式在现代社会的复杂环境下&#xff0c;逐渐显露出诸多弊端。内部管理分散混乱&#xff0c;人员、装备、物资管理缺乏统一标准和高效流程&#xff1b;外部监管困难重重…...

【Matlab】-- 基于MATLAB的美赛常用多种算法

文章目录 文章目录 01 内容概要02 各种算法基本原理03 部分代码04 代码下载 01 内容概要 本资料集合了多种数学建模和优化算法的常用代码资源&#xff0c;旨在为参与美国大学生数学建模竞赛&#xff08;MCM/ICM&#xff0c;简称美赛&#xff09;的参赛者提供实用的编程工具和…...

机器学习课程

前言 课程代码和数据文件&#xff1a; 一、机器学习概述 1.1.人工智能概述 机器学习和人工智能&#xff0c;深度学习的关系 机器学习是人工智能的一个实现途径深度学习是机器学习的一个方法发展而来 达特茅斯会议-人工智能的起点 1956年8月&#xff0c;在美国汉诺斯小镇宁静…...

AIGC(生成式AI)试用 28 -- 跟着清华教程学习 - AIGC发展研究 3.0

目标&#xff1a;继续学习 - 信息不对称、不平等、隐私泄露和数据滥用 - 问、改、创、优 - “概率预测&#xff08;快速反应&#xff09;”模型和“链式推理&#xff08;慢速思考&#xff09;”模型 - 思维滞环现象解决思路&#xff1a;1.调整提问&#xff1a;改变问题方式&…...

问题:md文档转换word,html,图片,excel,csv

文章目录 问题&#xff1a;md文档转换word&#xff0c;html&#xff0c;图片&#xff0c;excel&#xff0c;csv&#xff0c;ppt**主要职责****技能要求****发展方向****学习建议****薪资水平** 方案一&#xff1a;AI Markdown内容转换工具打开网站md文档转换wordmd文档转换pdfm…...

【Java】面向对象之static

用static关键字修饰成员变量 有static修饰成员变量&#xff0c;说明这个成员变量是属于类的&#xff0c;这个成员变量称为类变量或者静态成员变量。 直接用 类名访问即可。因为类只有一个&#xff0c;所以静态成员变量在内存区域中也只存在一份。所有的对象都可以共享这个变量…...

解决:在运行 plt.show()`时,程序会等待你手动关闭图片窗口才能继续往下执行

你这个问题本质是&#xff1a; 在运行 plt.show() 时&#xff0c;程序会等待你手动关闭图片窗口才能继续往下执行。 这其实是 matplotlib 的默认行为 —— 它会弹出一个交互式窗口让你“看完图再走”。 ✅ 为什么会这样&#xff1f; 你在程序中使用了&#xff1a; import mat…...

Anaconda安装-Ubuntu-Linux

1、进入Anaconda官网&#xff0c;以下载最新版本&#xff0c;根据自己的操作系统选择适配的版本。 2、跳过注册&#xff1a; 3、选择适配的版本&#xff1a; 4、cd ~/anaconda_download 5、bash Anaconda3-2024.10-1-Linux-x86_64.sh 6、按Enter或PgDn键滚动查看协议&…...

Linux 配置NFS服务器

1. 开放/nfs/shared目录&#xff0c;供所有用户查阅资料 服务端 &#xff08;1&#xff09;安装nfs服务&#xff0c;nfs-utils包中包含rpcbind&#xff08;rpc守护进程&#xff09; [rootnode1-server ~]# yum install -y nfs-utils # nfs-utils包中包含rpcbind [rootnode…...

css100个问题

一、基础概念 CSS的全称及作用是什么&#xff1f;行内样式、内部样式表、外部样式表的优先级&#xff1f;解释CSS的层叠性&#xff08;Cascading&#xff09;CSS选择器优先级计算规则伪类与伪元素的区别&#xff1f;举例说明!important的作用及使用注意事项如何继承父元素字体…...

塔能科技:用精准节能撬动社会效益的行业杠杆

在全球积极践行可持续发展理念的当下&#xff0c;能源高效利用与节能减排&#xff0c;已然成为各行各业实现高质量发展绕不开的关键命题。对企业来说&#xff0c;节能早已不是一道可做可不做的选择题&#xff0c;而是关乎生存与发展、社会责任与竞争力的必答题。塔能科技推出的…...

Java 大视界 -- Java 大数据在自动驾驶高精度地图数据更新与优化中的技术应用(157)

&#x1f496;亲爱的朋友们&#xff0c;热烈欢迎来到 青云交的博客&#xff01;能与诸位在此相逢&#xff0c;我倍感荣幸。在这飞速更迭的时代&#xff0c;我们都渴望一方心灵净土&#xff0c;而 我的博客 正是这样温暖的所在。这里为你呈上趣味与实用兼具的知识&#xff0c;也…...

Conda配置Python环境

1. 安装 Conda 选择发行版&#xff1a; Anaconda&#xff1a;适合需要预装大量科学计算包的用户&#xff08;体积较大&#xff09;。 Miniconda&#xff1a;轻量版&#xff0c;仅包含 Conda 和 Python&#xff08;推荐自行安装所需包&#xff09;。 验证安装&#xff1a; co…...

nginx https配置

一.https配置 HTTPS 协议是由HTTP 加上TLS/SSL 协议构建的可进行加密传输、身份认证的网络协议&#xff0c;主要通过数字证书、加密算法、非对称密钥等技术完成互联网数据传输加密&#xff0c;实现互联网传输安全保护。 1.生成证书 openssl genrsa -des3 -out server.key 20…...

每日一题洛谷P10901 [蓝桥杯 2024 省 C] 封闭图形个数c++

排序思想&#xff0c;只不过这时的排序与之前的略有不同&#xff0c;com函数中要先比较封闭图形再比较真实的大小&#xff0c;多了一步&#xff0c;但是原理还是一样的 #include<iostream> #include<algorithm> #include<vector> using namespace std; //统…...

拓展知识六:MetInfo6.0.0目录遍历漏洞原理分析

所需进行代码审计的文件路径&#xff1a; C:\phpStudy\WWW\MetInfo6.0.0\include\thumb.php C:\phpStudy\WWW\MetInfo6.0.0\app\system\entrance.php C:\phpStudy\WWW\MetInfo6.0.0\app\system\include\class\load.class.php C:\phpStudy\WWW\MetInfo6.0.0\app\system\include…...

tar包部署rabbitMQ

部署erlang&#xff1a; 有网使用&#xff1a; sudo apt-get update sudo apt-get install libncurses5-dev libncursesw5-dev sudo yum install ncurses-devel 无网使用 tar zxvf ncurses.tar.gz mkdir ncurses cd ncurses-6.3/ ./configure --with-shared --without-debu…...