Go’s interfaces—static, checked at compile time, dynamic when asked for—are, for me, the most exciting part of Go from a language design point of view. If I could export one feature of Go into other languages, it would be interfaces.
《Go Data Structures: Interfaces》—- Russ Cox
Golang接口的特点:所有实现接口T定义的所有方法的类型,都实现了接口T。
- 接口类型的构思,接口类型是一个罗列了一组方法的类型,因此要抽象一组方法来定义一个行为,那么就定义一个接口并声明这些方法
- 和大多数语言中的接口不同的是,Go里面没有“implements”声明,无须显式地说明“摸个具体类型实现了这个接口”,只要你定义了接口中的那些方法,它就自动实现了该接口
以io.Writer接口为例
io.Writer#####
io.Writer定义如下:
type Writer interface {
Write(p []byte) (n int, err error)
}```
根据Go中接口实现的特点,所有实现 ```Write(p []byte) (n int, err error)```方法的类型,都实现了io.Writer接口。
#####io.Writer的应用#####
在开发的过程中,我们经常使用```fmt.Println(a ...interface{ })```连打印信息到Terminal。fmt.Println的内部实现如下:
func Println(a ...interface{ }) (n int, err error) {
return Fprintln(os.Stdout, a...)
}```
fmt.Fprintln的函数签名:
func Fprintln(w io.Writer, a ...interface{}) (n int, err error)```
fmt.Fprintln接受的第一个参数为io.Witer类型,如果传入的第一个实参为io.File,内容便会被输出到该文件。如果传入的第一个实参是bytes.Buffer,那么,内容便输出到了buffer中。
如果想把内容输出到http响应体,可以这样做:
func Handler(rw http.ResponseWriter, req *http.Request) {
fmt.Fprintln(rw,"Hello,World!")
}```
os.Stdout的定义:
Stdout = NewFile(uintptr(syscall.Stdout),"/dev/stdout")```
可以看出,os.File也实现了io.Writer。
#####总结#####
Writer也是比较好理解的一个例子,Writer 由那些要做写操作的struct来实现。那么在做格式化输出时,fmt.Fprintf的第一参数不是os.File,而是io.Writer。这样,Fprintf可以给任何实现了write方法的struct做IO格式化的工作。比如HTTP服务中,可以使用fmt.Fprintf便可将数据传递到客户端,不需要任何花哨的操作。你可以通过任何'可写'东西来进行写操作:压缩器、加密机、缓存、网络连接、管道、文件,你都可以通过Fprintf直接操作,因为它们都实现了Write方法,因此,隐含都实现了io.Writer接口。