编码习惯&标准库[2.从WriteString看io.Writer接口]
go1.13.7 /Go/src/io/io.go:289
众所周知,go中是奉行接口实现解耦,继承,多态的银弹。特别是io.Reader,io.Writer这两个接口,是io的基本接口,标准库和第三方基础组件都实现了这两个函数。
type Reader interface {
Read(p []byte) (n int, err error)
}
type Writer interface {
Write(p []byte) (n int, err error
)}
下面通过WriteString()来看看接口的用法和作用,基于接口可以实现多态。
Writer当做参数传入函数内部,然后通过类型断言来判断传入的实现接口的真实对象类型,来达到自动调用对应实现的作用。
例如下面WriteString,内部对传入的w参数进行断言,如果实现了StringWriter接口,那么就调用其实现的StringWriter函数,即往实现WriteString的对象中直接写入字符串。若没有实现StringWriter接口,那么就调用Write实现,写入byte切片数据。
type StringWriter interface {
WriteString(s string) (n int, err error)
}
func WriteString(w Writer, s string) (n int, err error) {
if sw, ok := w.(StringWriter); ok {
return sw.WriteString(s)
}
return w.Write([]byte(s))
}
这样相当于实现了多态的特性,根据真实调用的情况而判断出其真实类型而调用其正确的实现方法。
小插曲,查了一下标准库,以下的标准库都实现了 io.Reader 和 io.Writer 二者或者其中之一。证明 io.Reader 和 io.Writer确实是标准库和开源库的基石。也验证了Go的设计理念,大量的“小接口”,组成“大接口”。
- os.File 同时实现了 io.Reader 和 io.Writer
- strings.Reader 实现了 io.Reader
- bufio.Reader/Writer 分别实现了 io.Reader 和 io.Writer
- bytes.Buffer 同时实现了 io.Reader 和 io.Writer
- bytes.Reader 实现了 io.Reader
- compress/gzip.Reader/Writer 分别实现了 io.Reader 和 io.Writer
- crypto/cipher.StreamReader/StreamWriter 分别实现了 io.Reader 和 io.Writer
- crypto/tls.Conn 同时实现了 io.Reader 和 io.Writer
- encoding/csv.Reader/Writer 分别实现了 io.Reader 和 io.Writer
- mime/multipart.Part 实现了 io.Reader
- net/conn 分别实现了 io.Reader 和 io.Writer(Conn接口定义了Read/Write)