一、前言
也许对这两个接口和相关的一些接口很熟悉了,但是你脑海里确很难形成一个对io接口的继承关系整天的概貌,原因在于godoc缺省并没有像javadoc一样显示官方库继承关系,这导致了我们对io接口的继承关系记忆不深,在使用的时候还经常需要翻文档加深记忆。
本文试图梳理清楚go io接口的继承关系,提供一个io接口的全貌。
二、io接口回顾
首先我们回顾一下几个常用的io接口。标准库的实现是将功能细分,每个最小粒度的功能定义成一个接口,然后接口可以组成成更多功能的接口。
最小粒度的接口
type reader interface { read(p []byte) (n int, err error) }
type writer interface { write(p []byte) (n int, err error) }
type closer interface { close() error }
type seeker interface { seek(offset int64, whence int) (int64, error) }
type readerfrom interface { readfrom(r reader) (n int64, err error) }
type writerto interface { writeto(w writer) (n int64, err error) }
type readerat interface { readat(p []byte, off int64) (n int, err error) }
type writerat interface { writeat(p []byte, off int64) (n int, err error) }
以及
type bytereader interface { readbyte() (byte, error) }
type bytewriter interface { writebyte(c byte) error }
bytescanner比bytereader多了一个unreadbyte
方法。
type bytescanner interface { bytereader unreadbyte() error }
type runereader interface { readrune() (r rune, size int, err error) }
type runescanner interface { runereader unreadrune() error }
组合接口
go标准库还定义了一些由上面的单一职能的接口组合而成的接口。
type readcloser interface { reader closer }
type readseeker interface { reader seeker }
type readwriter interface { reader writer }
type readwritecloser interface { reader writer closer }
type readwriteseeker interface { reader writer seeker }
type writecloser interface { writer closer }
type writeseeker interface { writer seeker }
从它们的定义上可以看出,它们是最小粒度的组合。
最小接口的扩展
有些结构体struct实现并且扩展了接口,这些结构体是。
type limitedreader struct { r reader // underlying reader n int64 // max bytes remaining }
type pipereader struct { // contains filtered or unexported fields }
type pipewriter struct { // contains filtered or unexported fields }
type sectionreader struct { // contains filtered or unexported fields }
下面我会将它们的继承关系画出来。
一些辅助方法
一些辅助方法可以生成特殊类型的reader或者writer:
func limitreader(r reader, n int64) reader func multireader(readers ...reader) reader func teereader(r reader, w writer) reader func multiwriter(writers ...writer) writer
三、继承关系
当然,go语言中并没有java中那样的继承关系,而是基于duck type形式实现,我用下图尝试展示go io接口的继承关系。
其中黄色是 bufio 包下的类型,
绿色是 archive.tar 包下的类型,
蓝色是 bytes 包下的类型,
粉红色是 strings包下的类型,
紫色是 crypto.tls 包下的类型。
rand是math.rand包下的类型。
file是os包下的内容。
`rand`左边的那个reader是image.jpeg下的内容。
我们最常用的是包io、bytes、bufio下的类型,所以这几个包下的类型要记牢,在第三库中经常会出现它们的身影。
上图中并没有把mime/multipart.file和 net/http.file列出来,主要是图太复杂了,它们实现的接口和os.file类似。
当然你可能会问,你怎么整理的它们的继承关系?事实上,你可以通过godoc -analysis=type -http=:6060生成带继承关系的go doc,并且它还可以将你本地下载的库中的继承关系也显示出来。
四、总结
以上就是关于go语言中io.reader和io.writer的详解与实现的全部内容,希望这篇文章的内容对大家的学习和工作能有所帮助,如果有疑问可以留言交流。
如对本文有疑问, 点击进行留言回复!!
VSCode1.4 搭建Golang的开发调试环境(遇到很多问题)
网友评论