Go語言中的io.Reader和io.Writer以及它們的實現

uu434zo56t 9年前發布 | 18K 次閱讀 IO Go語言 Google Go/Golang開發

在使用Go語言的過程中,無論你是實現web應用程序,還是控制臺輸入輸出,又或者是網絡操作,不可避免的會遇到IO操作,使用到io.Reader和io.Writer接口。也也許對這兩個接口和相關的一些接口很熟悉了,但是你腦海里確很難形成一個對io接口的繼承關系整天的概貌,原因在于godoc缺省并沒有像javadoc一樣顯示官方庫繼承關系,這導致了我們對io接口的繼承關系記憶不深,在使用的時候還經常需要翻文檔加深記憶。本文試圖梳理清楚Go io接口的繼承關系,提供一個io接口的全貌。

io接口回顧

首先我們回顧一下幾個常用的io接口。標準庫的實現是將功能細分,每個最小粒度的功能定義成一個接口,然后接口可以組成成更多功能的接口。

最小粒度的接口

typeReaderinterface{
 Read(p []byte) (nint, err error)
}
typeWriterinterface{
 Write(p []byte) (nint, err error)
}
typeCloserinterface{
 Close() error
}
typeSeekerinterface{
 Seek(offset int64, whenceint) (int64, error)
}
typeReaderFrominterface{
 ReadFrom(r Reader) (n int64, err error)
}
typeWriterTointerface{
 WriteTo(w Writer) (n int64, err error)
}
typeReaderAtinterface{
 ReadAt(p []byte, offint64) (nint, err error)
}
typeWriterAtinterface{
 WriteAt(p []byte, offint64) (nint, err error)
}

以及

typeByteReaderinterface{
 ReadByte() (byte, error)
}
typeByteWriterinterface{
 WriteByte(c byte) error
}

ByteScanner比ByteReader多了一個 UnreadByte 方法。

typeByteScannerinterface{
 ByteReader
 UnreadByte() error
}
typeRuneReaderinterface{
 ReadRune() (r rune, sizeint, err error)
}
typeRuneScannerinterface{
 RuneReader
 UnreadRune() error
}

組合接口

Go標準庫還定義了一些由上面的單一職能的接口組合而成的接口。

typeReadCloserinterface{
 Reader
 Closer
}
typeReadSeekerinterface{
 Reader
 Seeker
}
typeReadWriterinterface{
 Reader
 Writer
}
typeReadWriteCloserinterface{
 Reader
 Writer
 Closer
}
typeReadWriteSeekerinterface{
 Reader
 Writer
 Seeker
}
typeWriteCloserinterface{
 Writer
 Closer
}
typeWriteSeekerinterface{
 Writer
 Seeker
}

從它們的定義上可以看出,它們是最小粒度的組合。

最小接口的擴展

有些結構體struct實現并且擴展了接口,這些結構體是。

typeLimitedReaderstruct{
 R Reader // underlying reader
 N int64// max bytes remaining
}
typePipeReaderstruct{
// contains filtered or unexported fields
}
typePipeWriterstruct{
// contains filtered or unexported fields
}
typeSectionReaderstruct{
// contains filtered or unexported fields
}

下面我會將它們的繼承關系畫出來。

一些輔助方法

一些輔助方法可以生成特殊類型的Reader或者Writer:

funcLimitReader(r Reader, nint64) Reader
funcMultiReader(readers ...Reader) Reader
funcTeeReader(r Reader, w Writer) Reader

funcMultiWriter(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,并且它還可以將你本地下載的庫中的繼承關系也顯示出來。

參考文檔

  1. https://golang.org/pkg/io/
  2. https://golang.org/pkg/bufio/
  3. https://golang.org/pkg/bytes/
  4. https://medium.com/@benbjohnson/go-walkthrough-io-package-8ac5e95a9fbd#.er7vmwvb3
  5. https://medium.com/@blumenmann/a-simple-beginners-tutorial-to-io-writer-in-golang-2a13bfefea02#.sm0gq7rn0
  6. https://www.reddit.com/r/golang/comments/4z2eo2/noob_question_how_to_discover_interface/

 

來自:http://colobu.com/2016/08/29/go-io-Reader-and-io-Writer/

 

 本文由用戶 uu434zo56t 自行上傳分享,僅供網友學習交流。所有權歸原作者,若您的權利被侵害,請聯系管理員。
 轉載本站原創文章,請注明出處,并保留原始鏈接、圖片水印。
 本站是一個以用戶分享為主的開源技術平臺,歡迎各類分享!