嘿,Go 新手们(或者我应该说 Gophers-in-training?)! ?
界面似乎是每个人都在谈论的神秘而神奇的事物之一,但没有人真正以一种有意义的方式进行解释。 “这就像多态性,但更简单,”他们说。 “这就像一份合同,”他们声称。但每次我尝试实现一个时,我的代码都会看着我,“你到底在做什么,人类?” ?
但那是那时。现在,接口和我的关系好多了,我来这里是为了帮助您避免我早期的困惑。所以,如果你一直对 Go 接口摸不着头脑,那就喝杯咖啡(或茶),让我们一步一步地分解它——消除头痛。 ?
那么,接口到底是什么?
让我们从最顶层开始。在 Go 中,接口基本上是一种定义行为的方式,但不会被其工作细节所困扰。想象一下,你是一家工厂的老板,你并不关心机器是如何工作的;你只关心它能生产出产品。这就是 Go 接口的样子:您定义需要发生什么,但不定义应该如何完成。
例如,假设我们正在与动物一起工作(是的,Go 与动物一起工作,请留在这儿)。你知道每种动物都会发出声音,但你并不真正关心它是如何发生的。狗吠,猫喵喵,还有鸭子……嗯,它们嘎嘎叫。你可以像这样定义一个接口:
type Animal interface { Sound() string }
这是什么?只是一个契约,上面写着:“嘿,任何想要被称为 Animal 的类型都必须有一个 Sound() 方法。”就是这样!不涉及任何奇怪的巫术。
给我看代码! ???
让我们举一个超级简单的例子,看看它是如何工作的。我们将创造一些动物并让它们说话。
package main import "fmt" // The Animal interface type Animal interface { Sound() string } // Define a Dog type Dog struct{} func (d Dog) Sound() string { return "Woof!" } // Define a Cat type Cat struct{} func (c Cat) Sound() string { return "Meow!" } func main() { // Our Animal variable can hold any type that satisfies the interface var myPet Animal // myPet is now a Dog myPet = Dog{} fmt.Println(myPet.Sound()) // Outputs: Woof! // myPet is now a Cat myPet = Cat{} fmt.Println(myPet.Sound()) // Outputs: Meow! }
这里发生了什么事?
这就是 Go 界面的魔力真正发挥作用的地方 ??:
只要类型具有所需的方法,它就满足接口。无需明确地说“Dog 实现了 Animal”——Go 足够聪明,可以自己解决这个问题! ??
为什么要关心接口?
让我跟你说实话。起初,我想,“为什么还要麻烦这个呢?我可以直接写我的方法!”但相信我,您会希望尽快了解接口,尤其是当您的代码库开始增长时。
原因如下:
多态性:如果不同类型实现相同的接口,则可以统一对待它们。这就是界面如此强大的原因——就像拥有一个适用于任何电视的通用遥控器。
干净的代码:接口允许您编写更干净、更模块化的代码。您定义行为并让类型处理自己的实现。
多种方法,没问题!
让我们更上一层楼。假设您正在构建一个处理形状的系统,并且您想要计算圆形和矩形等不同形状的面积和周长。进入多方法界面!
type Animal interface { Sound() string }
空接口(接口{})
哦,你以为我们就完了???没有!让我们更深入地了解一下空接口,interface{},这是 Go 表达“我可以容纳任何类型”的方式。它就像一个免费的盒子,你可以在其中放入任何东西——字符串、数字、结构——只要你能想到的。
package main import "fmt" // The Animal interface type Animal interface { Sound() string } // Define a Dog type Dog struct{} func (d Dog) Sound() string { return "Woof!" } // Define a Cat type Cat struct{} func (c Cat) Sound() string { return "Meow!" } func main() { // Our Animal variable can hold any type that satisfies the interface var myPet Animal // myPet is now a Dog myPet = Dog{} fmt.Println(myPet.Sound()) // Outputs: Woof! // myPet is now a Cat myPet = Cat{} fmt.Println(myPet.Sound()) // Outputs: Meow! }
空接口通常用于您事先不知道要处理什么类型的情况(例如 API 或库)。这就像 Go 版本的通配符。
拥抱界面
学习 Go 界面一开始感觉就像在迷宫中行走,但是一旦掌握了基础知识,它就会打开一个灵活、可重用且干净的代码的全新世界。所以不要害怕投入其中!
从简单开始,玩一些小例子,让 Go 的界面魔力在你身上成长。不久之后,您将编写出像技术会议上的瑜伽教练一样干净灵活的代码。
地鼠同胞们,编码愉快!愿您的接口简单,并且您的结构能够不断实现。 ?✌️
以上是我如何不再担心并学会热爱 Go 界面的详细内容。更多信息请关注PHP中文网其他相关文章!