Go 言語のいろいろなパッケージを使ってみるシリーズ(目次)。 今回は io パッケージにたくさん定義されているインターフェース群をザッと見ていきます。 実装には立ち入りません。
io パッケージに定義されているインターフェースと定数
io パッケージに定義されているインターフェース型には以下のようなものがあります:// バイト I/O type ByteReader type ByteScanner type ByteWriter // ルーン I/O type RuneReader type RuneScanner // バイトスライス I/O type Reader type Writer type Seeker type Closer // Seeker のための定数 const ( SeekStart = 0 // ファイルの先頭から SeekCurrent = 1 // ファイルの現在の読み書き位置から SeekEnd = 2 // ファイルの末尾から ) type ReadWriter type ReadSeeker type ReadCloser type WriteSeeker type WriteCloser type ReadWriteCloser type ReadWriteSeeker // その他バイトスライス I/O type ReaderAt type ReaderFrom type WriterAt type WriterTo
以下でそれぞれの分類を見ていきましょう。
バイト I/O
バイト (byte) 1つずつ読み書きするために使うインターフェースには- io.ByteReader
- io.ByteScanner
- io.ByteWriter
の3つがあります。 それぞれの型の定義は簡単なので見ておきましょう:
type ByteReader interface{ ReadByte() (byte, error) } type ByteScanner interface{ ByteReader UnreadByte() error } type ByteWriter interface{ WriteByte(c byte) error }
クラス図っぽく書くとこんな感じ:
上図の矢印は継承っぽく書いてますが、Go には継承がなくコンポジションとなります。 ただし、ここでは代入可能な方向くらいの意味です:
var bs io.ByteScanner = strings.NewReader("Hello, world!") var br io.ByteReader = bs // 代入可能
ルーン I/O
Go のルーン (rune) は単なる int32 ですね。 上記のバイトの代わりに、ルーンを1つずつ読み込むインターフェースがあります:- io.RuneReader
- io.RuneScanner
ルーンを書き込む RuneWriter というのは定義されてないようです*1。 各インターフェースの定義は以下のようになっています:
type RuneReader interface{ ReadRune() (r rune, size int, err error) } type RuneScanner interface{ RuneReader UnreadRune() error }
クラス図風に書くとこんな感じ:
バイトスライス I/O
バイトやルーンを1つずつ読み書きするインターフェースはそれぞれ2~3個しかないので特にどうということはありませんが、バイトスライスの読み書きをするインターフェースは結構たくさんあります。 基本になるのは次の4つです:type Reader interface{ Read(p []byte) (n int, err error) } type Writer interface{ Write(p []byte) (n int, err error) } type Seeker interface{ Seek(offset int64, whence int) (int64, error) } type Closer interface{ Close() error }
io.Reader, io.Writer, io.Closer はいいでしょう。 io.Seeker は次に読み書きする位置を指定する Seek メソッドを持ち、ランダムアクセスできる入出力を表しています。 以前の「Go 言語の os パッケージにある File 型を使ってみる (2) : os.File のメソッド」で *os.File に定義されている Seek メソッドを使いました。
io.ReadWriter インターフェースなどは、これらの4つのインターフェースのいくつかを組み合わせて作られています:
type ReadWriter interface{ Reader Writer }
名前を見ればどのインターフェースを組み合わせているかは分かると思いますが、この種のインターフェースを図にして整理しておきましょう:
矢印はやはり代入可能な方向です。 結構ゴチャゴチャしてますが、io.Seeker と io.Closer を同時に実装している型は定義されていないというくらいが注意点でしょうか(os.File など、どちらも実装している具象型は他パッケージにありますが)。
その他バイトスライス I/O
上記のインターフェースの他にも、以下のバイトスライスを読み書きするインターフェースがあります:- io.ReaderAt
- io.ReaderFrom
- io.WriterAt
- io.WriterTo
それぞれに1つずつ実装すべきメソッドが定義されています:
type ReaderAt interface { ReadAt(p []byte, off int64) (n int, err error) } type ReaderFrom interface { ReadFrom(r Reader) (n int64, err error) } type WriterAt interface { WriteAt(p []byte, off int64) (n int, err error) } type WriterTo interface { WriteTo(w Writer) (n int64, err error) }
ここでは各メソッドの使い方は見ませんが、io.ReaderAt と io.WriterAt は *os.File によって実装されているので「Go 言語の os パッケージにある File 型を使ってみる (2) : os.File のメソッド」で使ってみました。 まぁ、名前から動作が分かると思いますが、指定した位置から読み書きをするランダムアクセス用のメソッド(型)です。 io.ReaderFrom, io.WriterTo は他のパッケージで具象型が出てきたときにやる予定(たぶん bufio パッケージ)。
今回は io パッケージに定義されているインターフェース型を見てきましたが、io パッケージにはここで見たインターフェースを実装するいくつかの具象型があるので、次回はそれらを使ってみる予定。
【追記】
- io.Seeker のための定数を追記しました。
プログラミング言語Go (ADDISON-WESLEY PROFESSIONAL COMPUTING SERIES)
- 作者: Alan A.A. Donovan,Brian W. Kernighan,柴田芳樹
- 出版社/メーカー: 丸善出版
- 発売日: 2016/06/20
- メディア: 単行本(ソフトカバー)
- この商品を含むブログ (2件) を見る
*1:バイトやバイトスライス、文字列を書き込める bufio.Writer には WriteRune メソッドも定義されてるんですが。