Golang 接口(interface) 简介和入门应用
如果在 公众号 文章发现状态为 已更新, 倡议点击 查看原文 查看最新内容。
状态: 未更新
原文链接: https://typonotes.com/posts/2023/02/28/devopscamp-interface-s...
上下文 interface
应该是 Go语言 中一个极其重要的 基石 概念了。
这里有一篇 Go 语言设计与实现 - 接口 interface , 是目前我学习的材料中 完成度 和 友善度 都很高的一篇文章。
在 go v1.18
中, interface
有了一个别名 any
。 所以在说 interface 和 any 的时候, 其实说的是雷同的货色。
interface
的应用场景到处都是。 还记得咱们之前说的 JSON
和 YAML
的配置文件解决吗?
// json.Marshalfunc Marshal(v any) ([]byte, error) {// ....}
看完文章, 你至多应该晓得
- 什么是 鸭式对象 ?
- 怎么应用 接口断言 ?
鸭式对象
先来说说 鸭式对象: 叫的像鸭子, 走路像鸭子, 那它就是鸭子。
- 咱们对鸭子下一个定义, 1. 收回嘎嘎的叫声, 2. 走路一摇一摆, 而后规定 任何满足这两个条件的 都是鸭子
咱们拿着定义去比照。
- 有一个 人 是演员, 他能模拟鸭子收回嘎嘎声, 也能模拟鸭子一摇一摆的走路。 那么, 这个人能被认为是鸭子。
- 有一个 玩具 , 能收回嘎嘎声, 也能一摇一摆的就走。 那么, 这个玩具也能被认为是鸭子。
简略的说, 接口就是 白名单定义, 满足白名单要求就行。
在下面形容中, 曾经提到了接口的两个重要概念: 定义 与 实现。
(1) 叫做 接口定义
type Duck interface{ Quack() Walk()}
(2) 叫做 接口实现
// 人type Person struct{}func (p *Person) Quack(){}func (p *Person) Walk(){}// 玩具type Toy struct{}func (t *Toy) Quack(){}func (t *Toy) Walk(){}
通过案例解说
咱们晓得, 人和大熊猫都是哺乳动物
- 他们都会 吃 (Eat) 吃货色, 区别是 人吃饭, 熊猫吃竹子
- 更大的不同是, 人会 读书 (Read), 熊猫不会。
func Eating(v any){ v.Eat() // output: ???}func WhoAreYou(v any){ // ???? }
接口定义
咱们回到作业要求, 要求实现 动物 和 人 两种接口。 要求
- 动物接口须要实现 吃 这个动作。
type Animal interface{ Eat()}
- 人接口 除了须要吃之外 , 还须要 读书 这个动作。
type Human interface{ Eat() Read()}
这种 间接为人定义两种办法 的形式是能够的, 然而当当前咱们要扩大动物接口, 增加 Walk
的时候, 也必须要为人增加 Walk
才行。 长此以往, 不仅难以治理, 还无奈从字面值上看到人和动物的关系。
那有没有更简略的形式呢? 有! 接口嵌套, Go 语言中没有继承概念。
type Human interface{ Read() Animal}
接口实现
咱们定两个 struct, 别离是 Panda 和 Child
type Panda struct{}func (p *Panda) Eat(){ fmt.Println("熊猫吃竹子")}// type Child struct{}func (c *Child) Eat(){ fmt.Println("人吃饭")}func (c *Child) Read(){ fmt.Println("人还会读书")}
这样, 小孩和熊猫的构造对象就定义好了, 他们实现了各自的办法。 并且满足之前人和动物的接口。
接口查看
在书写代码的过程中, 要查看一个构造对象是否齐全 实现了接口对应的所有办法, 防止在运行调用的时候才发现。
能够应用以下代码
var _ Person = &Child{}
这是一个 变量定义并赋值 的语句。 非凡的中央在于, 变量名应用了 下划线_
。
var peppa Person = &Child{} // 把 _ 换成了 peppa
如此操作
- 编译器在书写的时候就会进行语法查看。
- 创立的 不存在变量 最终会被抛弃。
接口断言
在日常应用中, 咱们能够通过 断言 将 接口A 转换成 接口B。
相似的, 就像问一头 熊猫 是不是 人?
func WhoAreYou(v any){ animal, ok := v.(Animal) // 断言, 判断 any 是否为能转换为 Animal if ok { animal.Eat() } child, ok := animal.(Human) // 断言 if ok { child.Read() }}
断言 返回的 第二个后果(ok) 是能够省略的。 不过这种用法须要用在咱们能 保障 转换肯定胜利的状况下。
animal := child.(Animal)
在这里, Human
嵌套了 Animal
办法, 所以转换肯定胜利。
相互吹捧, 共同进步
欢送和我一起学习提高, 如果有什么问题, 能够给我私信留言。 或者
- 加我好友 线下探讨。
- 关注我的 公众号 - 老麦胖熊猫 或者 B站账户 - 老麦胖熊猫 订阅最新文章和更多精彩内容