深入理解 Go 语言中的接口(interface)

一、GoLang 接口的定义

1、GoLang 中的接口
  • 在 Go 语言中接口(interface)是一种类型,一种抽象的类型
  • 接口(interface)定义了一个对象的行为规范,只定义规范不实现,由具体的对象来实现规范的细节
  • 实现接口的条件
    • 一个对象只要全部实现了接口中的方法,那么就实现了这个接口
    • 换句话说,接口就是一个需要实现的方法列表
2、定义一个 Usber 接口
  • 定义了一个 Usber 接口让 Phone 和 Camera 结构体实现这个接口
package mainimport "fmt"//1、接口是一个规范
type Usber interface {start()stop()
}//2.如果接口里面有方法的话,必要通过结构体或通过自定义类型实现这个接口
type Phone struct{Name string
}//3.手机摇实现 usb 接口的话必须先实现 usb 接口中的所有方法
func (p Phone) start() {fmt.PrintIn(p.Name,"启动")
}
func (p Phone) stop() {fmt.PrintfIn(p.Name,"关机")
}func main() {p := Phone{Name : "华为手机"}var p1 Usber    //golang中几口就是一个数据类型p1 = pp1.start()p1.stop()
}
/*
华为手机 启动
华为手机 关机*/

二、空接口

1、空接口说明
  • golang 中空接口也可以之间当做类型来使用,可以表示任意类型
  • Golang 中的接口可以不定义任何方法,没有定义任何方法的接口就是空接口
  • 空接口表示没有任何约束,因此任何类型变量都可以实现空接口
  • 空接口在实际项目中用的是非常多的,用空接口可以表示任意类型数据
2、空接口作为函数的参数
package mainimport "fmt"//空接口作为函数的参数func show (a interface{}){fmt.Printf("值:%v,类型:%T\n",a,a)
}func main(){show(20)        //值:20,类型:intshow("你好 golang")    //值:您好 golang 类型:stringslice := []int{1,2,34,5}show(slice)        //值:[1 2 34 5] 类型:[]int
}
3、切片实现空接口
package mainimport "fmt"func main() {var slice = []interface{}{"Snail",20,true,32.2}fmt.PrintIn(slice)    //[Snail 20 true 32.2]
}
4、map 的值实现空接口 
package mainimport "fmt"func main() {//空接口作为 map 值var studentInfo = make(map[string]interface{})studentInfo["name"] = "Snail"studentInfo["age"] = 18studentInfo["married"] = falsefmt.PrintIn(studentInfo)// [age:18 married:false name:Snail]
}

三、类型断言

  • 一个接口的值(简称接口值)是由一个具体类型和具体类型的值两部分组成的
  • 这两部分分别称为接口的动态类型和动态值
  • 如果我们想要判断空接口中值的类型,那么这个时候就可以使用类型断言
  • 其语法格式:x.(T)
    • x:表示类型为 interface{}的变量
    • T:表示断言x 可能是的类型
package mainimport "fmt"func main() {var x interface {}x = "hello golang"v,ok :=x.(string)if ok {fmt.PrintIn(v)}else {fmt.PrintIn("非字符串类型")}
}

四、值接收者和指针接收者

1、值接收者
  • 如果结构体中的方法是值接收者,那么实例化后的结构体值类型和结构体指针类型都可以赋值给接口变量
package mainimport "fmt"type Usb interface {Start()Stop()
}
type Phone struct {Name string
}
func (p Phone) Start() {fmt.PrintIn(p.Name,"开始工作")
}
func (p Phone) Stop() {fmt.Println("phone 停止")
}func main() {phone1 := Phone{Name:"华为手机"}var p1 Usb = phone1     //phone1 实现了 Usb接口 phone1 是 Phone 类型p1.Start()phone2 := &Phone{    //华为手机开始工作Name:"苹果手机"}var p2 Usb = phone2      //phone2 实现了 Usb 接口 phone2 是 *Phone 类型p2.Start() 
}
2、指针接收者
  • 如果结构体中的方法是指针接收者,那么实例化后结构体指针类型都可以赋值给接口变量,结构体值类型没法赋值给接口变量
package main
import "fmt"
type Usb interface {Start()Stop()
}
type Phone struct {Name string
}
func (p *Phone) Start() {fmt.Println(p.Name, "开始工作")
}
func (p *Phone) Stop() {fmt.Println("phone 停止")
}
func main() {/*错误写法phone1 := Phone{Name: "小米手机",}var p1 Usb = phone1p1.Start()*///正确写法phone2 := &Phone{Name: "苹果手机",}var p2 Usb = phone2 //phone2 实现了 Usb 接口 phone2 是 *Phone 类型p2.Start()//苹果手机 开始工作
}

五、一个结构体实现多个接口

  • Golang 中一个结构体也可以实现多个接口
package  mainimport "fmt"type AInterface interface {GetInfo() string
}
type Binterface interface {SetInfo(string,int)
}
type People struct{Name stringAge int
}func (p People) GetInfo() string(){return fmt.Sprintf("姓名:%v 年龄:%d",p.Name,p.Age)
}func (p *People) SetInfo(name string, age int) {p.Name = namep.Age = age
}func main() {ver people =&People{Name:"Snail",Age: 20,}// people实现了 Ainterface 和 Binterfacevar p1 AInterface = peoplevar p2 Binterface = peoplefmt.PrintIn(p1.GetInfo())    //姓名:Snail 年龄:20p2.SetInfo("pupu",21)fmt.PrintIn(p1.GEtInfo)      //姓名:pupu  年龄:21
}

六、接口嵌套

  • 接口与接口间可以通过嵌套创造出新的接口
package main import "fmt"type SayInterface interface {say()
}type MoveInterface interface {move()
}//接口嵌套
type Animal interface {SayInterfaceMoveInterface
}
type Cat struct {name string
}
func (c Cat) say() {fmt.PrintIn("喵喵喵")
}
func (c Cat) move(){fmt.PrintIn("猫会动")
}
func main() {var x Animalx = Cat{name: "花花"}x.move()    // 猫会动x.say()     // 喵喵喵
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/195872.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

0年费、0月费、免kyc,支持ChatGPTPlus充值虚拟卡

虚拟卡通常是指银行卡的虚拟卡,是在银行卡的基础上的银联、VISA、万事达卡BIN码衍生出的一种虚拟账户。虚拟卡一般都是用于网络上无卡支付,因此虚拟卡都不会配备相应的实体卡片。银行卡的虚拟卡,在分类上与实体卡并无什么区别,也分…

JAVA 可执行文件格式

JAVA 可执行文件格式 springboot 程序使用 Maven PLugin插件编译时,可以生成可执行的 jar 和 war 程序。其核心原理是 spring-boot-loader 模块,详细原理如下 1 嵌套 JARS java 本身不支持任何标准的加载嵌套 jar 的方式,要解决该问题&…

探秘高级代理技术:SK5代理在网络安全中的应用

在当今数字化时代,网络安全和隐私保护日益受到重视。作为网络工程师和网络文章主编,我将为您介绍一种强大而高级的代理技术——SK5代理,并探讨其在网络安全、爬虫以及HTTP通信中的重要应用。 1. SK5代理简介 SK5代理是一种基于SOCKS5协议的…

学SQL JOINS看这一篇文章就够了

目录 下面以实例进行分析 内连接 inner join 或者join(等同于inner join) 外连接 left join 或者left outer join(等同于left join) [ left join 或者left outer join(等同于left join) ] [ where B.column is null ] right join 或者right outer…

Docker Registry本地镜像仓库部署并实现远程连接拉取镜像

Linux 本地 Docker Registry本地镜像仓库远程连接 文章目录 Linux 本地 Docker Registry本地镜像仓库远程连接1. 部署Docker Registry2. 本地测试推送镜像3. Linux 安装cpolar4. 配置Docker Registry公网访问地址5. 公网远程推送Docker Registry6. 固定Docker Registry公网地址…

Centos系列:shell编程综合练习(个人学习记录)

shell编程综合练习(个人学习记录) shell编程until 循环跳出循环1. break命令2. continue 命令 Shell函数特殊变量输入输出重定向输出重定向输入重定向重定向 Shell实战监控centos7运行状态/proc/stat文件编写脚本free命令监控系统内存 shell编程 until …

ubuntu几个版本开启或关闭图形界面小结

在下面几个系统做过验证: ubuntu-16.04.7-desktop-amd64(内核版本:Linux 4.15.0-112) ubuntu-18.04.6-desktop-amd64(内核版本:Linux 5.4.0-150) ubuntu-20.04.6-desktop-amd64(内…

h5网站开发-微信浏览器无法自动播放视频的解决方式?

一、需求: 使用h5开发的网站,首页的banner是一个video视频,在PC端上和手机浏览器上都能正常播放,但是在手机微信浏览器里面视频是无法自动播放的。 二、实现效果: 1.微信浏览器的效果: 2.正常效果&…

如何实现高效代码审查,赋能大规模开发

对于许多企业来说,代码审查都是开发过程中不可缺少的一环。软件开发人员通常会对代码审查感到又爱又恨。一般来说,实施代码审查的企业普遍认为通过及早发现问题和低效率,在长远来看可节省时间。 阅读本篇文章,您将了解到什么是代…

JS浮点数精度问题及解决方案

前端面试大全JS浮点数精度问题及解决方案 🌟经典真题 🌟浮点数精度常见问题 🌟为什么会有这样的问题 🌟真题解答 🌟总结 🌟经典真题 为什么 console.log(0.20.10.3) 得到的值为 false 🌟…

vs-code之vue3插件

1.Vue 3 Support - All In One Vue3 代码片段突出显示了 Visual Studio Code 的格式化程序生成器 生成vue3对应的的代码 如ref等, 2.Volar 相信使用 VSCode 开发 Vue2 的同学一定对 Vetur 插件不会陌生,作为 Vue2 配套的 VSCode 插件,它的主…

C++学习之路(十)C++ 用Qt5实现一个工具箱(增加一个时间戳转换功能)- 示例代码拆分讲解

上篇文章,我们用 Qt5 实现了在小工具箱中添加了《JSON数据格式化》功能,还是比较实用的。为了继续丰富我们的工具箱,今天我们就再增加一个平时经常用到的功能吧,就是「 时间戳转换 」功能,而且实现点击按钮后文字进行变…

Unity中C#如何访问并修改Shader材质

文章目录 前言一、我们用点击按钮来改变Shader传入的颜色值1、在渲染GUI时,绘制一个按钮2、我们使用一个公共的成员变量存储需要进行修改的游戏对象3、最后给绘制的按钮点击增加逻辑即可 二、测试使用的代码1、Shader代码:2、C#脚本 前言 我们写好Shade…

电源自动测试系统| 电源模块温度循环怎么测试?

在一些应用领域,电源模块会在极端环境温度条件下工作。为了确保电源在高低温环境下可以正常运行,满足设备需求,需要对电源模块进行温度循环测试。 温度循环测试是指电源模块经过升温、保温、降温等多次循环试验来检测其在温度变化下的耐热性、…

关于自动化测试框架pytest的Fixture固件

什么是固件 Fixture 翻译成中文即是固件的意思。它其实就是一些函数,会在执行测试方法/测试函数之前(或之后)加载运行它们,常见的如接口用例在请求接口前数据库的初始连接,和请求之后关闭数据库的操作。 我们之前在A…

Hana Studio打开BW失败

Hana Studio打开BW失败 JCo initialization failed with java.lang.UnsatisfiedLinkError: D:\ycy\BW培训\HANA\configuration\org.eclipse.osgi\357\0.cp\lib\sapjco3.dll: Can’t find dependent libraries 这个提示应该是VC版本问题,按如下链接中的地址下载安装…

使用SD-WAN新方式,解锁分公司访问总部私有云

某企业是一家跨地区运营的大型企业,总部位于上海,拥有多个分公司遍布全国。其中北京分公司作为该企业在北方地区的重要分支机构,负责着该地区的市场开拓和业务发展。 为了实现分公司与总部之间的有效沟通和信息共享,北京分公司使用…

Linux快速配置拨号

在Linux上进行ADSL拨号配置,通常需要使用pppoeconf命令进行设置。pppoeconf是一个用于配置pppoe连接的工具,它可以帮助用户快速设置pppoe连接并生成配置文件。下面是一个详细的步骤指南,以帮助您在Linux上进行ADSL拨号配置。 步骤1&#xff…

ToDesk优惠码来了,需要的不容错过

最近发现Todesk也有活动了,很多小伙伴不知道,除了中秋国庆双节,ToDesk另有专享优惠码,输入优惠码最高立减25元,即使是活动日也能折上折,不影响此优惠码的折扣力度! Todesk作为国内优良的远程控制…

Centos系列:Centos7下的DNS服务器部署(每一步图文结合超详细,适用于初学者)

Centos7下的DNS服务器部署(每一步图文结合超详细,适用于初学者) Centos7下的DNS服务器部署引言部署步骤实验环境DNS服务端:DNS客户端: 正向解析安装DNS(DNS服务端,客户端都要操作)修…