[インデックス 16173] ファイルの概要
このコミットは、Go言語の標準ライブラリ src/pkg/testing/iotest/reader.go
内にある DataErrReader
の説明文を修正(rephrase)するものです。具体的には、DataErrReader
が io.Reader
のエラー処理の挙動をどのように変更するのかについて、より明確で理解しやすい記述に改善しています。
コミット
- コミットハッシュ:
d4d063580f3e684945e9f8dc470b2312fb27c5cf
- Author: Alexei Sholik alcosholik@gmail.com
- Date: Fri Apr 12 16:08:56 2013 -0700
- コミットメッセージ:
testing/iotest: rephrase DataErrReader's description R=r CC=golang-dev https://golang.org/cl/8650044
GitHub上でのコミットページへのリンク
https://github.com/golang/go/commit/d4d063580f3e684945e9f8dc470b2312fb27c5cf
元コミット内容
testing/iotest: rephrase DataErrReader's description
R=r
CC=golang-dev
https://golang.org/cl/8650044
変更の背景
この変更の背景には、DataErrReader
の既存のドキュメントが、その機能と io.Reader
の一般的なエラー処理パターンとの違いを十分に明確に説明していなかったという問題があります。Go言語の io.Reader
インターフェースは、データの読み取りとエラーの返却に関して特定の慣習を持っています。特に、データの終端(EOF)やその他のエラーは、通常、データがすべて読み取られた後の最初の Read
呼び出しで、0バイトのデータと共に返されます。
DataErrReader
はこの標準的な挙動を変更するため、その特殊な動作を正確かつ簡潔に説明することが重要です。以前の記述は「最終エラーを最後のデータと共に返す」という本質を捉えていましたが、それが通常の io.Reader
の挙動とどのように異なるのか、そしてなぜそれが重要なのかが不明瞭でした。このコミットは、この説明をより詳細かつ分かりやすくすることで、開発者が DataErrReader
の意図と使用法を正しく理解できるようにすることを目的としています。
前提知識の解説
io.Reader
インターフェース
Go言語における io.Reader
は、バイトストリームからデータを読み取るための基本的なインターフェースです。その定義は以下の通りです。
type Reader interface {
Read(p []byte) (n int, err error)
}
Read
メソッドは、p
スライスに最大len(p)
バイトのデータを読み込み、読み込んだバイト数n
とエラーerr
を返します。Read
メソッドは、n > 0
の場合でも非nilのエラーを返すことがあります。例えば、Read
がlen(p)
バイトを読み込んだが、その直後にエラーが発生した場合などです。- ストリームの終端に達した場合、
Read
は通常、n
を0とし、err
にio.EOF
を返します。ただし、ストリームの終端でまだ読み取れるデータがある場合、Read
はそのデータを返し、次のRead
呼び出しでio.EOF
を返すこともあります。 - 重要な慣習として、
io.Reader
は通常、すべてのデータが読み取られた後、次のRead
呼び出しでio.EOF
を返します。つまり、最後のデータはエラーなしで返され、その後のRead
呼び出しで初めてio.EOF
が返されるのが一般的です。
エラー処理の慣習
Goの io.Reader
におけるエラー処理の慣習は、特にストリームの終端(EOF)を扱う際に重要です。
- データとエラーの同時返却:
Read
メソッドは、読み取ったバイト数n
とエラーerr
を同時に返します。n > 0
であってもerr != nil
であることは有効です。これは、部分的な読み取りが成功し、かつエラーが発生した場合に起こります。 - EOFの扱い: ストリームの終端に達した場合、
Read
は通常、n=0
とerr=io.EOF
を返します。しかし、最後のデータブロックを読み取った直後のRead
呼び出しでio.EOF
が返されるのが一般的です。つまり、最後の有効なデータはエラーなしで読み取られ、その後にRead
を呼び出すとio.EOF
が返される、というシーケンスになります。
このコミットは、DataErrReader
がこの「最後のデータはエラーなしで返され、その後に io.EOF
が返される」という一般的な慣習をどのように変更するのかを明確に説明しようとしています。
技術的詳細
testing/iotest
パッケージは、io.Reader
や io.Writer
などの io
インターフェースの実装をテストする際に役立つユーティリティを提供します。これらのユーティリティは、特定の挙動を持つリーダーやライターをシミュレートし、それらを使用するコードが様々なシナリオで正しく動作するかを検証するために使われます。
DataErrReader
は、このパッケージが提供する特殊な io.Reader
のラッパーです。その主な目的は、通常の io.Reader
のエラー処理の慣習を意図的に変更することにあります。
通常の io.Reader
の挙動:
データがすべて読み取られた後、Read
メソッドは通常、次の Read
呼び出しで io.EOF
を返します。このとき、読み取られるバイト数 n
は0です。
DataErrReader
の挙動:
DataErrReader
は、この挙動を変更し、最後のデータが読み取られる際に、そのデータと共に最終的なエラー(通常は io.EOF
)を返します。つまり、n > 0
かつ err != nil
という形で、データとエラーが同時に返されるシナリオを強制的に作り出します。これは、一部の io.Reader
実装がこのような挙動を示す可能性があり、それに対応するコードのテストを可能にするために設計されています。
このコミットは、この DataErrReader
の特殊な挙動を、より正確かつ分かりやすい言葉で説明するようにコメントを修正しています。特に、「通常、リーダーは最後のデータが読み取られた後の最初の Read
呼び出しでエラーを返す」という一般的な挙動を明記し、DataErrReader
がそれを「最終エラーを最終データと共に返す」ように変更するという対比を明確にしています。
コアとなるコードの変更箇所
--- a/src/pkg/testing/iotest/reader.go
+++ b/src/pkg/testing/iotest/reader.go
@@ -37,9 +37,11 @@ func (r *halfReader) Read(p []byte) (int, error) {
return r.r.Read(p[0 : (len(p)+1)/2])
}
-// DataErrReader returns a Reader that returns the final
-// error with the last data read, instead of by itself with
-// zero bytes of data.
+// DataErrReader changes the way errors are handled by a Reader. Normally, a
+// Reader returns an error (typically EOF) from the first Read call after the
+// last piece of data is read. DataErrReader wraps a Reader and changes its
+// behavior so the final error is returned along with the final data, instead
+// of in the first call after the final data.
func DataErrReader(r io.Reader) io.Reader { return &dataErrReader{r, nil, make([]byte, 1024)} }\n
type dataErrReader struct {
コアとなるコードの解説
変更は DataErrReader
関数のコメント部分に集中しています。
変更前:
// DataErrReader returns a Reader that returns the final
// error with the last data read, instead of by itself with
// zero bytes of data.
この記述は、「最後のデータと共に最終エラーを返す」という DataErrReader
の本質を捉えていますが、なぜそれが重要なのか、そして通常の io.Reader
の挙動とどう異なるのかが不明瞭でした。「ゼロバイトのデータと共にそれ自体で」という表現もやや曖昧です。
変更後:
// DataErrReader changes the way errors are handled by a Reader. Normally, a
// Reader returns an error (typically EOF) from the first Read call after the
// last piece of data is read. DataErrReader wraps a Reader and changes its
// behavior so the final error is returned along with the final data, instead
// of in the first call after the final data.
新しい記述は、以下の点で大幅に改善されています。
- 目的の明確化: 「
Reader
のエラー処理方法を変更する」と明確に述べています。 - 通常の挙動の明記: 「通常、リーダーは最後のデータが読み取られた後の最初の
Read
呼び出しでエラー(通常はEOF
)を返す」と、一般的なio.Reader
のエラー処理の慣習を具体的に説明しています。これにより、DataErrReader
が何を変更するのかの基準が明確になります。 DataErrReader
の挙動の明確化: 「DataErrReader
はリーダーをラップし、その挙動を変更して、最終エラーが最終データと共に返されるようにする。最終データ後の最初の呼び出しで返されるのではなく」と、DataErrReader
の特殊な挙動を、通常の挙動との対比で非常に分かりやすく説明しています。
この修正により、DataErrReader
の機能と、それが io.Reader
の一般的なエラー処理パターンとどのように異なるのかが、より正確かつ詳細に伝わるようになりました。
関連リンク
- Go CL 8650044: https://golang.org/cl/8650044