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作为VOIP的软交换平台,需要对呼叫的信息做判断和归类. 常见的呼叫信息中,挂机方向的信息对于话单统计有很大的用处. 但是fs的原始话单和日志中并没有挂机方向的信息. 环境 ...
- docker容器常用操作
1.查看运行容器 docker ps: 2.查看所有容器 docker ps -a: 3.查看容器的日志 docker logs 容器名称/容器ID: 4.运行镜像 docker run --na ...
- Laravel - 使用 DB facade 实现CURD
<?php namespace App\Http\Controllers; use Illuminate\Http\Request; use Illuminate\Support\Facades ...
- [转帖]【linux命令学习】— sar 命令学习
https://blog.csdn.net/u013332124/article/details/101075521 一.命令使用介绍 sar命令全称 System Activity Report,它 ...
- [转帖]clickhouse 超底层原理& 高可用集群 实操(史上最全)
https://www.cnblogs.com/crazymakercircle/p/16718469.html 文章很长,而且持续更新,建议收藏起来,慢慢读!疯狂创客圈总目录 博客园版 为您奉上珍贵 ...
- [转帖]Nginx 保留 Client 真实 IP
https://lqingcloud.cn/post/nginx-01/#:~:text=%E5%9C%A8%20Nginx%20%E4%B8%AD%E5%8F%AF%E4%BB%A5%E9%80%9 ...
- [转帖]PostgreSQL 统计所有数据表各自的总行数
一般来说,可以使用 count(*) 来获取具体某张表的总行数: SELECT count(0) FROM t_user; 如果想获得所有表的行数信息,可以使用以下 SQL 语句: SELECT re ...
- [转帖]pyinstaller实现将python程序打包成exe文件
https://www.cnblogs.com/blogzyq/p/13939739.html 如果我们想要在一个没有python以及很多库环境的电脑上使用我们的小程序该怎么办呢? 我们想到,在Win ...
- [转帖]12.JVM运行时数据区之虚拟机栈概述
https://blog.csdn.net/u011069294/article/details/107050001 目录 1. 内存中的栈与堆 2.栈的优点 1. 内存中的栈与堆 栈是运行时单位,堆 ...
- CoreMark简单学习
CoreMark简单学习 下载 https://github.com/eembc/coremark-pro 需要注意, 其实coremark是有两组. 一组是coremark 一组是 coremark ...