基本定义

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. poj 2533 LIS(最长上升序列)

    ***一道裸题, 思路:在g数组内往里加元素,一直扩大这个数组,每次查询的时候,用二分查找,时间复杂度O(nlog(n)) *** #include<iostream> #include& ...

  2. 一文搞清楚Java中的包、类、接口

    写在开头 包.类.接口.方法.变量.参数.代码块,这些都是构成Java程序的核心部分,即便最简单的一段代码里都至少要包含里面的三四个内容,这两天花点时间梳理了一下,理解又深刻了几分. Java中的包 ...

  3. 基于java+springboot的宠物商店、宠物管理系统

    该系统是基于java+springboot开发的宠物商城,用户可以登录该网站购买宠物.该系统是给师弟开发的课程作业.运行过程中的问题,可以咨询github或留言. 演示地址 前台地址: http:// ...

  4. 6. 配置项:relabel_config

    6.1relabel_config的位置 6.2 relabel_config参数详解 1.replace 2. keep 3.drop 6.labelkeep 7.hashmod 6.3 正则表达式 ...

  5. SV 数据类型

    system verilog可以用于设计也可以进行验证 语法规则 SV新数据类型 SV数据类型 bit - 0-255 byte - -127 - 128 # 快速进行sv文件仿真 VCS -R -s ...

  6. 25-IP核简介

    1.IP IP(Intellectual Property)即知识产权,在半导体产业中讲IP核定义为用于"ASIC或FPGA中的预先设计好的电路功能模块".简言之,这里的IP即电路 ...

  7. [转帖]TLS 加速技术:Intel QuickAssist Technology(QAT)解决方案

    https://zhuanlan.zhihu.com/p/631184323   3 人赞同了该文章 作者:vivo 互联网服务器团队- Ye Feng 本文介绍了 Intel QAT 技术方案,通过 ...

  8. oceanbase部署维护命令学习

    oceanbase部署维护命令学习 背景 之前学习过TIDB数据库, 最近又准备学习一下Oceanbase数据库 发现其实两者还是比较相似的. 比较大的区别在于. TiDB是完全开源的, 并且比较明确 ...

  9. [转帖]Oracle进程中的 LOCAL=NO 和 LOCAL=YES

    https://www.cnblogs.com/wjoyxt/p/3780860.html 我们在服务器上用sqlplus 连接数据库,在查看进程,会多出一条记录: oracle 16007 1600 ...

  10. [转帖]关于虚拟化中cpu的指令集SSE 4.2的不支持

    背景: 局域网中有两台服务器proxmox进行了虚拟化,跑一些测试应用.今天正好想要安装一下clickhouse跑一下.安装前准备: 测试服务器是否支持sse 4.2指令集-如下 [root@slav ...