简单了解下 Interface

基本概念

来自于官方文档的说明: An interface type defines a type set . A variable of interface type can store a value of any type that is in the type set of the interface. Such a type is said to implement the interface

翻译:一个接口类型定义一个类型集合。接口类型的变量可以存储接口类型集合中任何类型的值。这样的类型被认为是实现了接口

重点是后面这段话,我们来进行分段解释。

  • 接口类型的变量可以存储接口类型集合中任何类型的值

    这意味着如果你有一个接口,该接口定义了一些方法,那么任何具有这些方法的类型的值都可以被存储在该接口类型的变量中

  • 这样的类型被认为是实现了接口

    在Go中,类型不需要显示声明它实现了某个接口。只要类型具有接口所需的所有方法,它就被视为实现了接口。

案例: 假设我们有以下的接口定义:

go 复制代码
type Duck interface {
    shout() string
}

现在,我们定义了两个类型,它们都有 shout 方法:

go 复制代码
type Dog struct {
    name string
}

func (dg Dog) shout() string {
    return dg.name + " is shouting"
}

type Bird struct {
    name string
}

func (bd Bird) shout() string {
    return bd.name + " is shouting"
}

由于Dog和Bird都有shout方法,他们都实现了Duck接口。因此,我们可以这样做:

go 复制代码
func main() {
    var duck Duck

    duck = Dog{name: "Dog"}
    fmt.Println(duck.shout()) // 输出:Dog is shouting

    duck = Bird{name: "Bird"}
    fmt.Println(duck.shout()) // 输出: Bird is shouting
}

在这个例子中,duck 是一个 Duck 接口类型的变量。尽管Dog和Bird是完全不同的类型,但由于它们都实现了Duck接口,所以它们的实例都可以赋值给duck变量,并调用它们的shout方法。

  • 接口不仅可以存储方法,还可以存储类型元素 我们先来看一个函数
go 复制代码
func speak[T float64 | float32 | int | string | rune | byte] () {}

上述案例声明了一个泛型函数speak,泛型T它表示float64 | float32 | int | string | rune | byte这些类型,如果还想为T增加类型,便还需往后面添加,不美观也不便于检查。那么我们就可以使用interface来表示。

go 复制代码
type GeneralType interface {
    float64 | float32 | int | string | rune | byte
}

func speak[T GeneralType] () {}

空接口

上文我们知道,如果一个类型满足接口的所有方法,该类型被认为实现了接口。当一个接口内没有定义任何方法(空接口),那么每个类型都被认为实现了它,使得它可以代表任何值。

go 复制代码
var anything interface{}

anything = 100
fmt.Println(anything) // 输出:100
anything = "3.141592653589793"
fmt.Println(anything) // 输出:3.141592653589793
anything = true
fmt.Println(anything) // 输出:true

嵌入式接口(Embedded interfaces)

经典套娃环节又来了,Go允许我们在接口内部除了写类型元素和方法,还可以写接口。表示合并了接口内部的所有方法

go 复制代码
type Dog interface {
    walk()
}

type Bird interface {
    shout()
}

type Animal interface {
    Dog()
    Bird()
}

Animal接口嵌套了 Dog和Bird接口,相当于合并了Dog接口和Bird接口内部的所有方法。

相关推荐
我不会起名字32214 小时前
微服务链路超时怎么设:逐层收敛的 4 条规则与 1 个反例
微服务·go·超时·熔断
我的div丢了肿么办20 小时前
go语言安装包详细讲解
后端·go
我不会起名字32221 小时前
Go 写 Kafka 消费者:sarama 的 3 个坑与优雅退出写法
kafka·消息队列·go·sarama
我不会起名字3221 天前
Redis 从 0 到 1(十一):缓存穿透/击穿/雪崩三连击,Go 3 套防御代码
redis·缓存·go·布隆过滤器·雪崩
bug菌2 天前
一个周末就想把短链服务推到 10 万 QPS,真能靠加 Redis 做到吗?
java·redis·go
tachibana22 天前
Go 语言里的 Context 是什么?
开发语言·后端·golang·go·语言
Linux实战笔记2 天前
sync.Mutex还是Channel?Go并发场景选型对比与goroutine泄漏实战
go·channel·sync.mutex·goroutine泄漏·race detector
wflynn2 天前
GitHub 今日推荐|open_scion:为AI代理设计的并发版本控制
git·开源·go·github·agent·coding-agents
Thinker QAQ2 天前
并发编程(九):BlockingQueue 与 Channel——语言层的原子性、可见性与有序性
java·python·go·并发编程·channel·blockingqueue·message passing
茉莉玫瑰花茶3 天前
GO [ 标准库 · unsafe ]
后端·go