1 概述
接口,interface,是用于规范对象应该具备哪些方法的技术。OOP中与结构体配合使用,对象使用结构体规范应该具有的书写,而对外通过接口暴露方法。Go 语言的接口设计是非侵入式的,接口实现者(也就是结构体)无须指明实现哪一个接口。编译器在编译时来确定使用哪个接口。
在 Go 语言中,接口是一种引用的数据类型出现的。但体现的功能是规范,而不是数据。
做 OOP 开发时,通常要保证一类操作具有相同的方法调用,此时就需要使用接口实现。
2 定义语法
type 接口名 interface { 接口中定义的规范方法列表 }
演示为:
// 定义接口 type Logger interface { // 写入一个日志事件 write(line string) int // 获取日志 fetch() string }
我们定义了一个 Logger 接口。其中定义了两个函数:write, fetch。
3 对象实现接口
依据接口定义,为对象定义相应方法,即为实现接口。接口设计是非侵入式的,因此不需要显式的在结构体上进行定义。
// 文件日志操作类(结构体) type FileLogger struct { } // 实现 Logger接口 func (fl *FileLogger) write(line string) int { // 功能不表 return 0 } func (fl *FileLogger) fetch() string { // 功能不表 return "" }
对象实现接口时,有以下几个特点:
- 一个类型对象可以实现多个接口,只需要将全部接口中定义的方法实现即可。注意接口间相互独立的,没有关联。
- 一个接口可以同时被多个类型对象实现。
- 一个接口的方法,可以通过内嵌结构体的方式来实现,不要求由一个结构体完全实现。
4 判断对象是否实现接口
我们通过将结构体对象赋值给接口对象的方式,来检测对象是否满足某个接口,演示为:
// 对象 fl := &FileLogger{} // 声明一个Logger类型接口 var log Logger // 将需要检测的对象,赋值给接口对象 // 如果可以赋值成功,说明满足接口限定,否则不满足 log = fl // 用一下接口,否则会报告变量定义未使用的错误 fmt.Println(log)
以上代码,若 fl 对象满足接口 log 的定义,赋值会成功。若没有满足,赋值失败,提示未实现接口的提示,提示类似于:
cannot use fl (type *FileLogger) as type Logger in assignment:
*fl does not implement Logger (missing wirte method)
同理,若函数的参数为接口类型,在调用函数时,传递的参数不满足接口,也会触发如上的错误:
// 参数 logger 为接口 Logger类型 func writeLog(logger Logger, line string) int { fmt.Println("Logger Run") // 实现略 return 0 } // 调用函数 // 对象 fl := &FileLogger{} writeLog(fl, "some log")
以上代码,若 fl 对象未满足接口 Logger 的定义,函数调用失败。提示类似的 does not implement 错误。
5 通过接口调用对象方法
当将对象赋值给接口后,检测通过,赋值成功。就可以使用接口调用对象方法了,此时对象方法接收器接收的对象还是原对象。直接赋值 和 函数调用赋值 都一样。
// 对象赋值给接口 log = fl // 调用对象方法 log.write("log line") // 函数参数也是如此 func writeLog(logger Logger, line string) int { // 调用对象方法 logger.write(line) return 0 }
6 空接口
空接口,没有定义任何成员的接口。
语法演示:
type any interface { }
由于没有定义任何的函数,意味着全部的对象都满足该接口。这个范围要扩大到全部数据类型上。不仅仅是对象。主要作用是类型通配,通常在定义函数时,表示函数可以接收任何类型的参数,例如 fmt.Print。
定义函数接收空接口类型参数时,可以使用 switch v.(type) 接口检测类型,这个结构称之为类型分支:
func sayType(v interface{}) { switch v.(type) { case bool: fmt.Println("bool") case float64: fmt.Println("float64") case string: fmt.Println("string") default: fmt.Println("其他类型") } }
7 接口间的嵌套
接口类似于接头体,可以嵌套,达到接口重用的目的。以系统 io 包定义的接口为例:
type Writer interface { Write(p []byte) (n int, err error) } type Closer interface { Close() error } // WriteCloser 接口 type WriteCloser interface { // 内嵌了 Write,Closer 接口 Writer Closer }
此时,若想实现 WriteCloser 接口,则 Writer 与 Closer 接口中定义的而方法需要全部实现。
完!
全部文章整理在:Go语言指导|小韩说课
原文出自:小韩说课
特别声明:以上文章内容仅代表作者本人观点,不代表变化吧观点或立场。如有关于作品内容、版权或其它问题请于作品发表后的30日内与变化吧联系。
- 赞助本站
- 微信扫一扫
-
- 加入Q群
- QQ扫一扫
-
评论