专栏首页twowinterGolang笔记 4.2 go 接口

Golang笔记 4.2 go 接口

1 它是什么

说背景和地位

摘录自《go语言编程》

接口在Go语言有着至关重要的地位。如果说goroutine和channel 是支撑起Go语言的并发模型的基石,让Go语言在如今集群化与多核化的时代成为一道极为亮丽的风景,那么接口是Go语言整个类型系统的基石,让Go语言在基础编程哲学的探索上达到前所未有的高度。

Go语言在编程哲学上是变革派,而不是改良派。这不是因为Go语言有goroutine和channel,而更重要的是因为Go语言的类型系统,更是因为Go语言的接口。 Go语言的编程哲学因为有接口而趋近完美。

Go语言的非侵入式接口,看似只是做了很小的文法调整,实则影响深远。

侵入式接口,“侵入式”的主要表现在于实现类需要明确声明自己实现了某个接口。

一句话说明

接口提供了一种方式来说明对象的行为:如果谁能搞定这件事,它就可以用在这儿。

接口定义了一组方法(方法集),但是这些方法不包含(实现)代码:它们没有被实现(它们是抽象的)。

所以一句话来说,接口是使用方法的抽象。

2 为什么需要它

接口是使用方法的抽象,使当前程序可以更聚焦在方法的应用,不关心该方法的具体实现。

3 怎么用

接口赋值

接口定义:

type Integer int
func (a Integer) Less(b Integer) bool {
	return a < b
}
func (a *Integer) Add(b Integer) {
	*a += b
}

type LessAdder interface {
	Less(b Integer) bool
	Add(b Integer)
}

接口赋值,将实例赋值给接口:

var a Integer = 1
var b LessAdder = &a

接口查询

var file1 Writer = ...
if file5, ok := file1.(two.IStream); ok {
	...
}

Writer接口的实现实例file1,是否实现了 two.IStream 接口,如果实现了则执行代码。

类型查询

在 Go 语言中,还可以更加直截了当地询问接口指向的对象实例的类型。

利用反射也可以进行类型查询,详情可参阅reflect.TypeOf()方法。

var v1 interface{} = ...
switch v := v1.(type) {
	case int: // 现在v的类型是int
	case string: // 现在v的类型是string
	...
}

接口组合

type ReadWriter interface {
	Reader
	Writer
}

这个接口组合了Reader和Writer两个接口,它完全等同于如下写法:

type ReadWriter interface {
	Read(p []byte) (n int, err error)
	Write(p []byte) (n int, err error)
}

4 示例

典型示例 关注使用,不操心接口实现。来自于《GO示例学》。

// 这里定义了一个最基本的表示几何形状的方法的接口

type geometry interface {
  area() float64
  perim() float64
}

// 这里不管正方形或者长方形怎么去实现自己的接口,但最后使用部分,直接用接口方法就好了。

func measure(g geometry) {
  fmt.Println(g)
  fmt.Println(g.area())
  fmt.Println(g.perim())
}

5 空接口 Any类型

由于Go语言中任何对象实例都满足空接口interface{},所以interface{}看起来像是可以指向任何对象的 Any 类型,如下:

var v1 interface{} = 1 // 将int类型赋值给interface{}
var v2 interface{} = "abc" // 将string类型赋值给interface{}
var v3 interface{} = &v2 // 将*interface{}类型赋值给interface{}
var v4 interface{} = struct{ X int }{1}
var v5 interface{} = &struct{ X int }{1}

当函数可以接受任意的对象实例时,我们会将其声明为interface{},最典型的例子是标准库 fmt 中 PrintXXX 系列的函数,例如:

传入参数是 可变数量的 任意类型。

func Printf(fmt string, args ...interface{})
func Println(args ...interface{})

总体来说, 我们刚开始对 interface{} 一无所知,但可以通过接口查询和类型查询逐步了解它。

6 小结

总结,接口是使用方法的抽象,使当前程序可以更聚焦在方法的应用,不关心该方法的具体实现。后续的应用程序在做具体实现时,再去完善具体实现,不会影响之前程序已经定义好的逻辑。

更通俗地来讲,接口的定义,就像是设置了一个岗位,描述了岗位的职责;,一些规章可以先根据岗位职责来制定,不关心具体是谁来任职这个岗位。当应用程序开始执行的时候,需要给接口传入一个实例,相当于企业开始运营时再把一个人放到这个岗位。

另外空接口 interface{} 作为 Any 类型也有很广到应用。

END

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • The Things Network LoRaWAN Stack V3 学习笔记 2.7.1 Web 前端开发调试

    上一篇研究了如果编译运行 Web 前端,这一篇研究如何在开发模式下调试 Web 前端。

    twowinter
  • 零java基础搞定微信Server_4_写一个servlet的DEMO

    完善了开发环境之后,就是编写servlet示例程序了,感受下javaweb的开发。

    twowinter
  • CC1310空中升级笔记04 WSN OAD Example

    关于CC1310的空中升级,让我折腾了特别久,我几乎绝望了。仅有的两个参考资料都遇到了困难: 1.CC2640 OAD,其中的BIM部分,TI只提供了IAR...

    twowinter
  • 腾讯TMQ沙龙|接口测试理论与实践

    接口测试理论与实践 活动时间:2016年8月11日 QQ群视频交流 活动介绍 : TMQ在线沙龙第六期分享 本次分享的主题是接口测试理论与实践相关的知识。 共...

    腾讯移动品质中心TMQ
  • JAVA面试50讲之8:谈谈接口和final类的区别

    抽象类是用来捕捉子类的通用特性的 。它不能被实例化,只能被用作子类的超类。抽象类是被用来创建继承层级里子类的模板。以JDK中的GenericServlet为例:

    用户1205080
  • Onvif/RTSP网络安防摄像机网页无插件直播方案EasyNVR接口调用返回出现“Unauthorized”解决方案

    EasyNVR可以将局域网/广域网上的海康/大华等网络摄像头由rtsp转换为rtmp、rtsp、hls、flv协议转换,并提供推流服务,可以将拉到的网络摄像头直...

    EasyNVR
  • 「JAVA」Java面向对象之面向接口编程,细节都在这里了

    比如,显示器中封装了很多电子元器件,这些元器件连接在一起为显示器的正常共工作提供支持,那显示器如何与外界的其他设备(如电脑主机、外放音响、耳机等设备)通信交互呢...

    老夫编程说
  • Java之接口详解

    接口(英文:Interface),就是比“抽象类”还“抽象”的“抽象类”,可以更加规范的对子类进行约束。全面地专业地实现了,规范和具体实现的分离。

    用户5224393
  • 什么?接口中方法可以不是抽象的「JDK8接口新语法的深度思考」

    在传统的接口语法中,接口中只可以有抽象方法。在是在实际的使用中,我们往往会需要用到很多和接口相关的功能(方法),这些功能会单独的拿出开放在工具类中。

    鹿老师的Java笔记
  • 接口测试

    模拟客户端向服务器发送请求,服务器接收请求后对相应的请求做处理并向客户端返回响应结果,客户端接收结果的一个过程

    zx钟

扫码关注云+社区

领取腾讯云代金券