Go语言中io.Reader和io.Writer的详解与实现

2020-01-28 12:07:04刘景俊

一、前言

也许对这两个接口和相关的一些接口很熟悉了,但是你脑海里确很难形成一个对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
}

从它们的定义上可以看出,它们是最小粒度的组合。