GO学习之 接口(Interface)

这篇具有很好参考价值的文章主要介绍了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)
10、GO学习之 网络通信(Net/Http)
11、GO学习之 微框架(Gin)
12、GO学习之 数据库(mysql)
13、GO学习之 数据库(Redis)
14、GO学习之 搜索引擎(ElasticSearch)
15、GO学习之 消息队列(Kafka)
16、GO学习之 远程过程调用(RPC)
17、GO学习之 goroutine的调度原理

前言

按照公司目前的任务,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 main

import "fmt"

// 定义一个图形接口,方法是求图形的面积
type Shape interface {
	Area() float64
}

// 定义一个矩形
type Rectangle struct {
	Width  float64
	Height 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

	// 创建一个矩形并赋值给接口 shape
	shape = Rectangle{Width: 5, Height: 10}
	fmt.Printf("矩形的面积是:%+v\n", shape.Area())

	// 创建一个圆形并赋值给接口 shape
	shape = 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 main

import "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 ShapeArea
	var spaceRound ShageRound

	// 实例化 Sequre 结构体
	s := Sequre{Side: 9}

	// 赋值给接口 spaceArea 以求面积
	spaceArea = s
	fmt.Printf("正方形的面积是:%+v\n", spaceArea.Area())

	// 赋值给接口 spaceRound 以求周长
	spaceRound = s
	fmt.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 main

import "fmt"

// 定义接口 表示可以说话
type Sayer interface {
	say()
}

// 定义接口,表示可以移动
type Mover interface {
	move()
}

// 接口嵌套
type Animal interface {
	Sayer
	Mover
}

// 定义结构体类型 猫咪
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 Animal
	yuanbao = Cat{Name: "元宝"}
	yuanbao.say()
	yuanbao.move()
}

运行结果:

PS D:\workspaceGo\src\interface> go run .\interfaceNested.go
喵咪 元宝 在叫'喵喵喵'
猫咪 元宝 在上蹿下跳

3.4 空接口

此示例中定义了一个空接口,既然接口是一种类型,不关心实现,那我们可以借助空接口来实现接受任何类型参数,类似于JAVA中的 Object 超类,可以接受任何参数,可以作为函数的参数,也可以放在 map 中以便此 map 存放任何类型的值。

package main

import "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"] = 25
	myInfo["hobby"] = "运动,看书,数钱"
	myInfo["rich"] = false
	fmt.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 main

import "fmt"

// 定义一个图形接口,方法是求图形的面积
type Shape interface {
	Area() float64
}

// 定义一个矩形
type Rectangle struct {
	Width  float64
	Height float64
}

// 矩形实现了 Shape 接口中求面积的 Area 方法
func (r Rectangle) Area() float64 {
	return r.Width * r.Height
}

func main() {
	// 定义一个接口类型变量
	var shape Shape

	// 接口断言,如果 ok = true, 则 rect 的类型为 Rectangle
	if rect, ok := shape.(Rectangle); ok {
		fmt.Printf("矩形的面积为 %+v\n", rect.Area())
	} else {
		fmt.Println("接口 shape 不包含 Rectangle 的值")
	}

	// 创建一个矩形并赋值给接口 shape
	shape = Rectangle{Width: 5, Height: 10}

	// 接口断言,如果 ok2 = true, 则 r 的类型为 Rectangle
	if 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 语言中是非常重要的特性,它提供了一种约定和抽象的方式,让不同的类型可以用相同的方式处理。在实际开发中有许多用途和场景,重要包括:

  1. 实现多态性:让不同类型以相同方式处理,提高代码的灵活性和复用性
  2. 解耦代码:通过接口将代码解耦,使得不同模块直接依赖较少,从而提高代码的可维护性
  3. 实现设计模式:接口类型可以很好的支持如 工厂模式、策略模式等这些模式的实现,让代码更加简洁易于维护和理解
  4. 扩展性和适配器模式:通过接口,可以很好的扩展程序的功能,只需实现相应的方法即可,同时接口也可以适用于不同的模块,将不同的类型适配成统一的接口类型,实现代码的复用和扩展
  5. 测试和模拟:在单元测试中,可以利用接口来模拟依赖项,实现代码的测试隔离。通过使用接口,可以方便的替换真实的依赖实现,从而实现对代码的独立测试

总而言之,接口类型在 Go 语言中非常灵活和强大,它可以帮助我们实现面向接口编程,提高代码的灵活性和可复用性,减少代码的耦合性,使得代码更加清晰、简洁和易于维护。在实际开发中,合理地使用接口类型,可以使代码更加健壮和可扩展,提高开发效率和质量。

现阶段还是对 Go 语言的学习阶段,想必有一些地方考虑的不全面,本文示例全部是亲自手敲代码并且执行通过。
如有问题,还请指教。
评论去告诉我哦!!!一起学习一起进步!!!文章来源地址https://www.toymoban.com/news/detail-633615.html

到了这里,关于GO学习之 接口(Interface)的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • golang学习之go连接Kafka

    1、Kafka 本质上是⼀个消息队列,一个高吞吐量、持久性、分布式的消息系统。 2、包含生产者(producer)和消费者(consumer),每个consumer属于一个特定的消费者组(Consumer Group)。 3、生产者生产消息(message)写入到kafka服务器(broker,kafka集群的节点),消费者从kafka服务器

    2023年04月09日
    浏览(37)
  • go 结构体 - 值类型、引用类型 - 结构体转json类型 - 指针类型的种类 - 结构体方法 - 继承 - 多态(interface接口) - 练习

    目录 一、结构体 1、python 与 go面向对象的实现: 2、初用GO中的结构体:(实例化一个值类型的数据(结构体)) 输出结果不同的三种方式  3、实例化一个引用类型的数据(结构体) 4、引用类型(指针类型) vs 值类型(两者的区别) 引用类型(指针类型) - 值类型内存拓扑图:

    2024年02月14日
    浏览(54)
  • Golang扫盲式学习——GO并发 | (一)

    并行:同一个时间段内多个任务同时在不同的CPU核心上执行。强调同一时刻多个任务之间的” 同时执行 “。 并发:同一个时间段内多个任务都在进展。强调多个任务间的” 交替执行 “。 随着硬件水平的提高,现在的终端主机都是多个CPU,每个CPU都是多核结构。当多个CPU同

    2024年02月07日
    浏览(45)
  • golang interface类型的nil

    golang中interface变量,底层两个对象来存,一个是type、一个是value,只有type、value都为nil时,interface变量才是nil 输出结果为: 可以看到interface 变量i,虽然值为nil,但类型是Student 如果想判断变量value是否为空,可以指定type

    2024年02月14日
    浏览(33)
  • 《UE5_C++多人TPS完整教程》学习笔记15 ——《P16 会话接口委托(Session Interface Delegates)》

    本文为B站系列教学视频 《UE5_C++多人TPS完整教程》 —— 《P16 会话接口委托(Session Interface Delegates)》 的学习笔记,该系列教学视频为 Udemy 课程 《Unreal Engine 5 C++ Multiplayer Shooter》 的中文字幕翻译版,UP主(也是译者)为 游戏引擎能吃么。 本节课我们将向新创建的子系统添

    2024年02月20日
    浏览(51)
  • golang 类型转换interface转字符串string

    方式一和方式二适用于interface和各种转换 方式三如果需要将一个普通的类型转换成字符串,可以使用 strconv 包中的相关函数。例如,将一个整数转换成字符串:

    2024年02月12日
    浏览(47)
  • 学习如何在VS Code中创建一个Golang/Go项目,并运行一个简单的Golang程序

     学习如何在VS Code中创建一个Golang项目,并运行一个简单的Golang程序。 在VS Code 手动输入命令创建一个Golang项目 在VS Code 不输入命令创建一个Golang项目 1. 在VS Code 手动输入命令创建一个Golang项目 步骤1:在VS Code中创建一个新文件夹,用于存放Golang项目文件。 步骤2:打开VS

    2024年02月14日
    浏览(61)
  • go语言(十三)-----interface

    一、Interface 通用万能类型 空接口 int,string,float,struct都实现了interface 都可以用interface{}类型,引用任意的数据类型

    2024年01月23日
    浏览(34)
  • go interface 基本用法

    Go 中接口也是一个使用得非常频繁的特性,好的软件设计往往离不开接口的使用,比如依赖倒置原则(通过抽象出接口,分离了具体实现与实际使用的耦合)。 今天,就来给大家介绍一下 Go 中接口的一些基本用法。 Go 中的接口跟我们常见的编程语言中的接口不太一样,go 里

    2024年01月21日
    浏览(31)
  • Go interface基础

    接口类型是对其它类型行为的概括与抽象。通过使用接口,我们可以写出更加灵活和通用的函数,这些函数不用绑定在一个特定的类型实现上。 很多面向对象的语言都有接口这个概念,Go 语言的接口的独特之处在于它是隐式实现。换句话说,对于一个具体的类型,无须声明它

    2024年01月20日
    浏览(33)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包