Go 之烧脑的接口
基本定义
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 接口。
接口类型断言
再来看一个很复杂的例子,我们将上面的代码稍作修改,将 Wechat 的 Login 和 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 之烧脑的接口的更多相关文章
- Swift 烧脑体操(二) - 函数的参数
前言 Swift 其实比 Objective-C 复杂很多,相对于出生于上世纪 80 年代的 Objective-C 来说,Swift 融入了大量新特性.这也使得我们学习掌握这门语言变得相对来说更加困 ...
- 个人永久性免费-Excel催化剂功能第85波-灵活便捷的批量发送短信功能(使用腾讯云接口)
微信时代的今天,短信一样不可缺席,大系统都有集成短信接口.若只是临时用一下,若能够直接在Excel上加工好内容就可以直接发送,这些假设在此篇批量群发短信功能中都为大家带来完美答案. 业务场景 不多说, ...
- App开发:模拟服务器数据接口 - MockApi
为了方便app开发过程中,不受服务器接口的限制,便于客户端功能的快速测试,可以在客户端实现一个模拟服务器数据接口的MockApi模块.本篇文章就尝试为使用gradle的android项目设计实现Moc ...
- 干货来袭-整套完整安全的API接口解决方案
在各种手机APP泛滥的现在,背后都有同样泛滥的API接口在支撑,其中鱼龙混杂,直接裸奔的WEB API大量存在,安全性令人堪优 在以前WEB API概念没有很普及的时候,都采用自已定义的接口和结构,对 ...
- 12306官方火车票Api接口
2017,现在已进入春运期间,真的是一票难求,深有体会.各种购票抢票软件应运而生,也有购买加速包提高抢票几率,可以理解为变相的黄牛.对于技术人员,虽然写一个抢票软件还是比较难的,但是还是简单看看123 ...
- Java基础Map接口+Collections工具类
1.Map中我们主要讲两个接口 HashMap 与 LinkedHashMap (1)其中LinkedHashMap是有序的 怎么存怎么取出来 我们讲一下Map的增删改查功能: /* * Ma ...
- Java基础Map接口+Collections
1.Map中我们主要讲两个接口 HashMap 与 LinkedHashMap (1)其中LinkedHashMap是有序的 怎么存怎么取出来 我们讲一下Map的增删改查功能: /* * Ma ...
- java基础_集合List与Set接口
List接口继承了Collection的方法 当然也有自己特有的方法向指定位置添加元素 add(索引,添加的元素); 移除指定索引的元素 remove(索引) 修改指定索引的元素 set ...
- 【WCF】自定义错误处理(IErrorHandler接口的用法)
当被调用的服务操作发生异常时,可以直接把异常的原始内容传回给客户端.在WCF中,服务器传回客户端的异常,通常会使用 FaultException,该异常由这么几个东东组成: 1.Action:在服务调 ...
- PHP以接口方式实现多重继承(完全模拟)--学习笔记
1.UML类图: 2.PHP代码: <?php /** * Created by PhpStorm. * User: andy * Date: 16-11-23 * Time: 下午7:57 ...
随机推荐
- freeswitch的任务引擎问题与解决方案
概述 freeswitch核心框架中有一个定时任务系统task,在开发过程中用来做一些延时操作和异步操作很方便. 我们在VOIP的呼叫流程中,经常会有一些对实时性要求没那么高的操作,或者会有阻塞流程的 ...
- RL 的探索策略 | Exploration for RL
最近在草率地调研 RL 的 exploration. 这篇文章也比较草率,仅能起到辅助作用,不能代替读 review 或更精细的读 paper. 目录 0 总结写在最前面 1 主要参考资料 2 RL ...
- citespace 文献计量工具初探
先放几个教程: 知乎 - CiteSpace 使用教程 - 312 赞同 知乎 - CiteSpace 入门教程 - 949 赞同 简书 - 研究方法 | 用 CiteSpace 进行科学文献可视化分 ...
- Linux 中常用的基础命令
by emanjusaka from https://www.emanjusaka.top/2024/01/linux-base-command 彼岸花开可奈何 本文欢迎分享与聚合,全文转载请留下原文 ...
- HanLP — 感知机(Perceptron)
感知机(Perceptron)是一个二类分类的线性分类模型,属于监督式学习算法.最终目的: 将不同的样本分本 感知机饮食了多个权重参数,输入的特征向量先是和对应的权重相乘,再加得到的积相加,然后将加权 ...
- CSS - 工具类 tool.css
/* flex */ .flex{ display: flex; } .f1{ flex:1 } .flex-center{ align-items: center; ...
- [转帖]【sql server安全】sql server连接加密,sql server SSL加密连接
https://www.cnblogs.com/gered/p/13595098.html#_label1_0 MSSQL - 最佳实践 - 使用SSL加密连接 回到顶部 author: 风移 回到顶 ...
- [转帖]备份VCSA内置Postgresql数据库
首先命令行远程登录到VCSA服务器,然后执行如下命令停掉VCSA的核心服务vmware-vpxd: vCenterServerAppliance:~ # service vmware-vpxd sto ...
- Python学习之七_input和print
Python学习之七_input和print 摘要 python3 之后 函数必须带 () 了 因为我开始学习的比较晚, 所以准备Python3开始学起 前面主要是模仿别人的代码进行学习 后续慢慢学习 ...
- [转帖]linux shell 脚本一些主要知识点整理
文章目录 一./bin/sh 与 /bin/bash 的区别 二.vi与vim的区别 三.shell变量 四.Shell字符串 五.Shell函数 六.Shell基本运算符 1.Shell expr: ...