关于后端:Go-通过一个案例解释清楚-interface-的用法和注意事项

33次阅读

共计 1996 个字符,预计需要花费 5 分钟才能阅读完成。

Golang 接口(interface) 简介和入门应用

如果在 公众号 文章发现状态为 已更新 ,倡议点击 查看原文 查看最新内容。

状态: 未更新

原文链接: https://typonotes.com/posts/2023/02/28/devopscamp-interface-s…

上下文 interface 应该是 Go 语言 中一个极其重要的 基石 概念了。

这里有一篇 Go 语言设计与实现 – 接口 interface,是目前我学习的材料中 完成度 友善度 都很高的一篇文章。

go v1.18 中,interface 有了一个别名 any。所以在说 interface 和 any 的时候,其实说的是雷同的货色。

interface 的应用场景到处都是。还记得咱们之前说的 JSONYAML 的配置文件解决吗?

// json.Marshal
func Marshal(v any) ([]byte, error) {// ....}

看完文章,你至多应该晓得

  1. 什么是 鸭式对象
  2. 怎么应用 接口断言

鸭式对象

先来说说 鸭式对象: 叫的像鸭子,走路像鸭子,那它就是鸭子。

  1. 咱们对鸭子下一个定义,1. 收回嘎嘎的叫声,2. 走路一摇一摆 ,而后规定 任何满足这两个条件的 都是鸭子
  2. 咱们拿着定义去比照。

    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(){}

通过案例解说

咱们晓得,人和大熊猫都是哺乳动物

  1. 他们都会 吃 (Eat) 吃货色,区别是 人吃饭,熊猫吃竹子
  2. 更大的不同是,人会 读书 (Read),熊猫不会。
func Eating(v any){v.Eat() // output: ???
}

func WhoAreYou(v any){// ????}
接口定义

咱们回到作业要求,要求实现 动物 两种接口。要求

  1. 动物接口须要实现 这个动作。
type Animal interface{Eat()
}
  1. 人接口 除了须要吃之外 ,还须要 读书 这个动作。
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 

如此操作

  1. 编译器在书写的时候就会进行语法查看。
  2. 创立的 不存在变量 最终会被抛弃。

接口断言

在日常应用中,咱们能够通过 断言 接口 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 办法,所以转换肯定胜利。

相互吹捧,共同进步

欢送和我一起学习提高,如果有什么问题,能够给我私信留言。或者

  1. 加我好友 线下探讨。
  2. 关注我的 公众号 – 老麦胖熊猫 或者 B 站账户 – 老麦胖熊猫 订阅最新文章和更多精彩内容

正文完
 0