基本定义

Go 官方对于接口的定义是一句话:An interface type is defined as a set of method signatures. 翻译过来就是,一个接口定义了一组方法的集合。这和 Java 和 PHP 的接口类似,定义一组方法而不定义方法的具体实现。但是与 Java 和 PHP 迥然不同的地方在于 Go 不需要显式的声明 implements 关键词来继承接口,一个类型只要实现了接口中的所有方法,就视作继承了该接口,是隐式实现的。来看一个基本的使用示例:

// 定义一个平台接口,包含一个支付方法
type Platform interface {
Pay(amount int) error
} // 微信平台
type Wechat struct{} func (w *Wechat) Pay(amount int) error {
fmt.Printf("wechat amount: %d\n", amount)
return nil
} // 支付宝平台
// 任意值都可以实现接口,并非一定需要struct
type Alipay int func (a Alipay) Pay(amount int) error {
fmt.Printf("alipay amount: %d, a: %d\n", amount, a)
return nil
} func ExamplePlatform() {
var (
p Platform
w = Wechat{}
a Alipay = 1
)
p = &w
p.Pay(2) p = &a
p.Pay(3) // 这种写法会报错
// p = w
p = a
p.Pay(4) // Output:
// wechat amount: 2
// alipay amount: 3, a: 1
// alipay amount: 4, a: 1
}

在这个示例中,我们定义了一个 Platform 接口和两个结构体,分别使用了值接收器和指针接收器来实现了 Platform 接口。p = w 这行代码会报错,究其原因是,对于使用指针接收器实现的接口的 Wechat,只有它的指针会实现接口,值不会实现;而对于值实现接口的 Alipay,指针和值都会实现接口。所以 p = a 可以正常运行。

接口嵌套

接口可以嵌套另一个接口:

// 定义一个平台接口,包含一个支付方法
type Platform interface {
Pay(amount int) error
User
} type User interface {
Login()
Logout()
} // 微信平台
type Wechat struct{} func (w *Wechat) Pay(amount int) error {
fmt.Printf("wechat amount: %d\n", amount)
return nil
} func (w *Wechat) Login() {}
func (w *Wechat) Logout() {}

此时,Wechat 即实现了 Platform 接口,也实现了 User 接口。

接口类型断言

再来看一个很复杂的例子,我们将上面的代码稍作修改,将 WechatLogin Logout 提到另一个结构中,然后使用类型断言判断 Wechat 是否实现了 User 接口:

// 定义一个平台接口,包含一个支付方法
type Platform interface {
Pay(amount int) error
User
} type User interface {
Login()
Logout()
} type UserS struct {
} func (u *UserS) Login() {}
func (u *UserS) Logout() {} // 微信平台
type Wechat struct {
UserS
} func (w *Wechat) Pay(amount int) error {
fmt.Printf("wechat amount: %d\n", amount)
return nil
} func ExamplePlatform() {
var (
p Platform
w = Wechat{}
)
p = &w
p.Pay(2) // 类型断言
_, ok := p.(User)
fmt.Println(ok) // Output:
// wechat amount: 2
// true
}

空接口

Go 1.18 新增了一个新的变量类型:any,其定义如下:

type any = interface{}

其实 any 就是一个空接口,对于空接口而言,它没有任何方法,所以对于任意类型的值都相当于实现了空接口,这个概念和另一个编程概念十分相似,它就是大名鼎鼎的泛型。在 Go 语言中,fmt.Println 函数的接收值正是一个 any

func Println(a ...any) (n int, err error) {
return Fprintln(os.Stdout, a...)
}

使用空接口搭配类型断言,我们可以设计出一个简单的类型转换函数,它将任意类型的值转为 int:

func ToInt(i any) int {
switch v := i.(type) {
case int:
return v
case float64:
return int(v)
case bool:
if v {
return 1
}
return 0
case string:
vint, _ := strconv.Atoi(v)
return vint
} return 0
}

Go 之烧脑的接口的更多相关文章

  1. Swift 烧脑体操(二) - 函数的参数

    前言 Swift 其实比 Objective-C 复杂很多,相对于出生于上世纪 80 年代的 Objective-C 来说,Swift 融入了大量新特性.这也使得我们学习掌握这门语言变得相对来说更加困 ...

  2. 个人永久性免费-Excel催化剂功能第85波-灵活便捷的批量发送短信功能(使用腾讯云接口)

    微信时代的今天,短信一样不可缺席,大系统都有集成短信接口.若只是临时用一下,若能够直接在Excel上加工好内容就可以直接发送,这些假设在此篇批量群发短信功能中都为大家带来完美答案. 业务场景 不多说, ...

  3. App开发:模拟服务器数据接口 - MockApi

    为了方便app开发过程中,不受服务器接口的限制,便于客户端功能的快速测试,可以在客户端实现一个模拟服务器数据接口的MockApi模块.本篇文章就尝试为使用gradle的android项目设计实现Moc ...

  4. 干货来袭-整套完整安全的API接口解决方案

    在各种手机APP泛滥的现在,背后都有同样泛滥的API接口在支撑,其中鱼龙混杂,直接裸奔的WEB API大量存在,安全性令人堪优 在以前WEB API概念没有很普及的时候,都采用自已定义的接口和结构,对 ...

  5. 12306官方火车票Api接口

    2017,现在已进入春运期间,真的是一票难求,深有体会.各种购票抢票软件应运而生,也有购买加速包提高抢票几率,可以理解为变相的黄牛.对于技术人员,虽然写一个抢票软件还是比较难的,但是还是简单看看123 ...

  6. Java基础Map接口+Collections工具类

    1.Map中我们主要讲两个接口 HashMap  与   LinkedHashMap (1)其中LinkedHashMap是有序的  怎么存怎么取出来 我们讲一下Map的增删改查功能: /* * Ma ...

  7. Java基础Map接口+Collections

    1.Map中我们主要讲两个接口 HashMap  与   LinkedHashMap (1)其中LinkedHashMap是有序的  怎么存怎么取出来 我们讲一下Map的增删改查功能: /* * Ma ...

  8. java基础_集合List与Set接口

    List接口继承了Collection的方法  当然也有自己特有的方法向指定位置添加元素   add(索引,添加的元素); 移除指定索引的元素   remove(索引) 修改指定索引的元素   set ...

  9. 【WCF】自定义错误处理(IErrorHandler接口的用法)

    当被调用的服务操作发生异常时,可以直接把异常的原始内容传回给客户端.在WCF中,服务器传回客户端的异常,通常会使用 FaultException,该异常由这么几个东东组成: 1.Action:在服务调 ...

  10. PHP以接口方式实现多重继承(完全模拟)--学习笔记

     1.UML类图: 2.PHP代码: <?php /** * Created by PhpStorm. * User: andy * Date: 16-11-23 * Time: 下午7:57 ...

随机推荐

  1. 如何与chatgpt共存

    作为程序员,专注于创造性劳动,而把重复性劳动任务交给chatgpt,要成为 需求 和 chatgpt的桥梁. 人工智能比如chatgpt越来越强,提问能力是人类的天赋,提问能力更为重要.

  2. 15-TTL与非门

    TTL与非门 集成电路有两大类COMOS和TTL(三极管) 电路结构 工作原理 多发射结的三极管,两个输入之间是与的关系 输入低电平 输入高电平 A.B都是高电平 倒置放大 压差大的先导通 T3,T4 ...

  3. 【TouchGFX】实测工程所在路径深度不可超过10级(10级有效)

    实测环境 win10 64bit touchgfx designer 4.13.0

  4. Hexo中引入另一个文件内容

    有的时候博客内容会有变动,首发博客是最新的,其他博客地址可能会未同步,认准https://blog.zysicyj.top 首发博客地址 安装插件 npm install hexo-include-m ...

  5. IBM jca 工具的学习与整理

    IBM jca 工具的学习与整理 背景 发现自己最早看到IBM这个工具的时间是 2022年9月份. 但是一直没有进行过仔细的学习与论证. 本周出现了一个问题. 虽然通过gclog明显看出来是一个oom ...

  6. 快速部署minio的一个思路

    快速部署minio的一个思路 背景 小型项目上希望能够快速部署一些中间件. 因为minio比较简单,想着快速一键部署. 加快工作效率. 这里将脚本和思路写下来, 其他应用可以一样进行. 思路 1. 下 ...

  7. tiup 工具离线安装与简单导出数据说明

    tiup 工具离线安装说明 mirror的创建 能上网的机器上面进行如下操作: curl --proto '=https' --tlsv1.2 -sSf https://tiup-mirrors.pi ...

  8. [转帖]Shell编程之免交互

    目录 交互的概念与Linux中的运用 Here Document 免交互 tee命令重定向输出加标准输出 支持变量替换 多行注释 Expect 实例操作 免交互预设值修改用户密码 创建用户并设置密码 ...

  9. [转帖]一文解决内核是如何给容器中的进程分配CPU资源的?

    https://zhuanlan.zhihu.com/p/615570804   现在很多公司的服务都是跑在容器下,我来问几个容器 CPU 相关的问题,看大家对天天在用的技术是否熟悉. 容器中的核是真 ...

  10. [转帖]记录几个常用linux命令的使用方法——find、grep、file、which、whereis和压缩命令gzip、bzip2、tar

    一.命令1: find.grep.file.which.whereis 1.find 目的:查找符合条件的文件 1)在哪些目录中查找 2)查找的内容 格式: find 目录名 选项 查找条件 举例: ...