《10节课学会Golang-08-Interface》

微信关注【面试情报局】我们一起干翻面试官, 回复golang获取本文源码
视频地址:b站 10节课学会Golang,Go快速入门

Interface

Go语言中,interface是一种类型,用于定义一组方法签名。一个实现了这些方法的具体类型被称为这个interface的实现类型。接口类型是一种抽象的类型,它不会暴露出所包含的具体值的内部结构和数据。

同时interface 类型可以代表任意类型的值,因此它可以用来定义不同类型的值。

定义接口

接口类型通常用于将具体类型的实现细节与实现类型的名称分离开来。它们可以帮助我们构建高度抽象的代码,使代码更加灵活、易于维护和扩展。同时,Go语言中的接口类型也提供了一种非常强大的面向对象编程机制,使得Go语言的面向对象编程变得更加自然和简单。

package main

import "fmt"

// Duck 接口类型 定义一组方法签名的集合
// 定义接口约定
type Duck interface {
	GaGaga()
	// ....
}

type DonaldDuck string

func (d DonaldDuck) GaGaga() {
	fmt.Printf("%s, ga ga ga\n", d)
}

type RubberDuck string

func (d RubberDuck) GaGaga() {
	fmt.Printf("%s, ga ga ga\n", d)
}

type Dog struct {
	Name string
	age  int
}

func (d Dog) GaGaga() {
	fmt.Printf("%s, ga ga ga\n", d.Name)
}

func main() {
	var d Duck

	d = DonaldDuck("🦆 唐老鸭")
	d.GaGaga()

	d = RubberDuck("🦆 小黄鸭")
	d.GaGaga()

	d = Dog{
		Name: "小狗",
		age:  5,
	}
	d.GaGaga()
}

以上代码定义了一个接口类型 Duck,并定义了三个实现该接口的具体类型 DonaldDuckRubberDuckDog

其中,DonaldDuckRubberDuck 都实现了 GaGaga() 方法,可以输出 xxx, ga ga ga 的字符串,而 Dog 类型也实现了 GaGaga() 方法,但是输出的是该狗的名字,而不是 ga ga ga

main 函数中,定义了一个 Duck 类型的变量 d,并将 DonaldDuckRubberDuckDog 类型的变量赋值给 d,这是因为这三个类型都实现了 Duck 接口,所以可以赋值给 Duck 类型的变量。

然后分别调用 dGaGaga() 方法,根据不同的类型,输出不同的字符串。

接口断言

接口断言是指从一个接口类型中提取出具体的值和类型信息的操作。在 Go 中,接口断言可以使用类型断言的方式进行实现。如果一个接口变量 x 的底层类型是 T 类型,我们可以使用 x.(T) 的方式对其进行类型断言,其中 .(T) 表示将 x 转换为 T 类型。

package main

import "fmt"

// 类型断言
// 断言 interface
func main() {
	var i interface{} = "hello"

	s := i.(string)
	fmt.Println(s)

	// 类型断言, 断言失败一般会导致panic的发生, 所以为了防止panic的发生, 我们需要在断言前进行一定的判断。
	// 如果断言失败, 那么ok的值将会是false
	// 如果断言成功, 那么ok的值将会是true, 同时s将会得到正确类型的值。
	s, ok := i.(string)
	fmt.Println(s, ok)

	f, ok := i.(float64)
	fmt.Println(f, ok)

	f = i.(float64) // 报错(panic)
	fmt.Println(f)
}

在代码中,变量 i 的类型为 interface{},表示它可以保存任何类型的值。然后使用 .(string) 进行类型断言,将其转换为字符串类型,并将结果赋值给变量 s

接下来使用类型断言和布尔值的组合形式,将 i 断言为字符串类型,并将结果分别赋值给 sok。由于 i 的实际类型是字符串类型,因此断言成功,ok 的值为 trues 得到了正确类型的值。

然后尝试将 i 断言为 float64 类型,这次断言失败,ok 的值为 falsef 的值为 0

最后尝试将 i 直接断言为 float64 类型,由于实际类型是字符串类型,所以这次断言会导致 panic 异常的发生。

为什么需要接口

  • 接口允许 Go 具有多态性, 在需要多态性的 Go 中使用接口。
  • 在可以传递多种类型的函数中,可以使用接口。
  • 接口还用于帮助减少重复/样板代码。

在需要动态类型参数的函数和方法的情况下,接口非常有用,例如接受任何类型值的 Println 函数。

思考题

参考

https://blog.knoldus.com/how-to-use-interfaces-in-golang/

https://stackoverflow.com/questions/39092925/why-are-interfaces-needed-in-golang

https://stackoverflow.com/questions/23148812/whats-the-meaning-of-interface

https://blog.boot.dev/golang/golang-interfaces/


系列文章

《10节课学会Golang-01-Package》
《10节课学会Golang-02-变量与常量》
《10节课学会Golang-03-函数》
《10节课学会Golang-04-流程控制》
《10节课学会Golang-05-结构体》
《10节课学会Golang-06-数组与切片》
《10节课学会Golang-07-Map》
《10节课学会Golang-08-Interface》
《10节课学会Golang-09-Goroutine》
《10节课学会Golang-10-Channel》

微信关注【面试情报局】我们一起干翻面试官, 回复golang获取本文源码

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

HTML网页设计-期末大作业

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值