[インデックス 11768] ファイルの概要
このコミットは、Go言語の標準ライブラリstrings
パッケージ内のreader.go
ファイルに対する変更です。具体的には、Reader
型のUnreadByte
、ReadRune
、UnreadRune
メソッドから、それらが満たすインターフェースによって暗黙的に示されるコメントを削除しています。これにより、コードの冗長性が排除され、Goのドキュメンテーション慣習に沿った形に修正されています。
コミット
commit 4c7695126d881b4622ed74238d7ce5c4e6b3b259
Author: Rob Pike <r@golang.org>
Date: Fri Feb 10 14:45:11 2012 +1100
strings: delete method comments implied by interface satisfaction
Fixes #2957.
R=golang-dev, bradfitz
CC=golang-dev
https://golang.org/cl/5653053
GitHub上でのコミットページへのリンク
https://github.com/golang/go/commit/4c7695126d881b4622ed74238d7ce5c4e6b3b259
元コミット内容
strings: delete method comments implied by interface satisfaction
Fixes #2957.
R=golang-dev, bradfitz
CC=golang-dev
https://golang.org/cl/5653053
変更の背景
この変更は、Go言語のドキュメンテーション慣習と、インターフェースの暗黙的な実装という言語特性に基づいています。Goでは、ある型が特定のインターフェースのすべてのメソッドを実装していれば、その型はそのインターフェースを「満たす」と見なされます。この際、implements
のような明示的なキーワードは不要です。
strings.Reader
型は、io.ByteReader
インターフェース(ReadByte()
メソッドを持つ)やio.RuneReader
インターフェース(ReadRune()
メソッドを持つ)などを満たしています。Goのドキュメンテーション慣習では、インターフェースのメソッドがそのインターフェースの定義によって十分に説明されている場合、そのメソッドの実装側で冗長なコメントを繰り返すことは推奨されません。
このコミットは、Go issue #2957("godoc: don't show method comments for interface satisfaction")に関連しており、godoc
ツールがインターフェースを満たすメソッドのコメントをどのように表示すべきかという議論の結果として行われました。インターフェースのメソッドは、そのインターフェース自体で十分にドキュメント化されているべきであり、個々の実装で同じ説明を繰り返すのは冗長であるという考え方です。これにより、ドキュメンテーションの重複を避け、コードの可読性を向上させることが目的です。
前提知識の解説
Go言語のインターフェースと暗黙的な実装
Go言語のインターフェースは、メソッドのシグネチャの集合を定義します。Goの型は、インターフェースで定義されたすべてのメソッドを実装していれば、そのインターフェースを自動的に満たします。これを「暗黙的なインターフェースの実装(implicit interface satisfaction)」と呼びます。例えば、io.Reader
インターフェースはRead([]byte) (int, error)
メソッドを定義しており、このメソッドを持つ任意の型はio.Reader
として扱えます。
io.ByteReader
インターフェース
io
パッケージに定義されているByteReader
インターフェースは、単一のReadByte()
メソッドを持ちます。
type ByteReader interface {
ReadByte() (c byte, err error)
}
このインターフェースを実装する型は、バイトストリームから1バイトずつ読み込む機能を提供します。
io.RuneReader
インターフェース
io
パッケージに定義されているRuneReader
インターフェースは、単一のReadRune()
メソッドを持ちます。
type RuneReader interface {
ReadRune() (r rune, size int, err error)
}
このインターフェースを実装する型は、UTF-8エンコードされたUnicodeコードポイント(rune)を読み込む機能を提供します。ReadRune
は、読み込んだルーン、そのルーンが占めるバイト数、およびエラーを返します。
Goのドキュメンテーション慣習
Goのドキュメンテーションは、godoc
ツールによって生成されます。Goのドキュメンテーション慣習では、エクスポートされた(大文字で始まる)型、関数、メソッド、変数、定数には、その直前にドキュメンテーションコメントを記述します。
特に、インターフェースのメソッドがそのインターフェースの定義によって十分に説明されている場合、そのメソッドの実装側で同じ内容のコメントを繰り返すことは冗長と見なされます。インターフェースのコメントが、そのインターフェースの目的と各メソッドの振る舞いを明確に説明していれば、実装側のメソッドコメントは、その実装固有の詳細や注意点に限定されるべきです。
技術的詳細
strings.Reader
型は、文字列を読み込むためのio.Reader
、io.ByteReader
、io.RuneReader
などのインターフェースを満たすように設計されています。
このコミット以前は、strings.Reader
のUnreadByte
、ReadRune
、UnreadRune
メソッドには、それぞれのメソッドが何をするかを説明するコメントが付与されていました。しかし、これらのメソッドはそれぞれio.ByteReader
やio.RuneReader
インターフェースのメソッドを実装しており、これらのインターフェース自体がそのメソッドの振る舞いを定義し、ドキュメント化しています。
Goのドキュメンテーションの哲学では、インターフェースのメソッドがそのインターフェースの定義によって十分に説明されている場合、そのメソッドの実装側で同じ説明を繰り返すことは冗長であり、メンテナンスの負担を増やすと考えられます。例えば、io.ByteReader
のReadByte()
メソッドの機能は、io.ByteReader
インターフェースのドキュメントで明確に定義されています。strings.Reader
のReadByte()
がそのインターフェースを満たす以上、そのメソッドが「バイトを読み込む」という基本的な機能を持つことは自明です。
したがって、このコミットでは、インターフェースによって暗黙的に示される機能に関するコメントを削除することで、ドキュメンテーションの重複を排除し、コードをより簡潔に保っています。これにより、godoc
で生成されるドキュメントもより洗練され、ユーザーはインターフェースのドキュメントを参照することで、そのメソッドの基本的な振る舞いを理解できるようになります。
コアとなるコードの変更箇所
--- a/src/pkg/strings/reader.go
+++ b/src/pkg/strings/reader.go
@@ -50,9 +50,6 @@ func (r *Reader) ReadByte() (b byte, err error) {
return
}
-// UnreadByte moves the reading position back by one byte.
-// It is an error to call UnreadByte if nothing has been
-// read yet.
func (r *Reader) UnreadByte() error {
if r.i <= 0 {
return errors.New("strings.Reader: at beginning of string")
@@ -62,11 +59,6 @@ func (r *Reader) UnreadByte() error {
return nil
}
-// ReadRune reads and returns the next UTF-8-encoded
-// Unicode code point from the buffer.
-// If no bytes are available, the error returned is io.EOF.
-// If the bytes are an erroneous UTF-8 encoding, it
-// consumes one byte and returns U+FFFD, 1.
func (r *Reader) ReadRune() (ch rune, size int, err error) {
if r.i >= len(r.s) {
return 0, 0, io.EOF
@@ -81,9 +73,6 @@ func (r *Reader) ReadRune() (ch rune, size int, err error) {
return
}
-// UnreadRune causes the next call to ReadRune to return the same rune
-// as the previous call to ReadRune.
-// The last method called on r must have been ReadRune.
func (r *Reader) UnreadRune() error {
if r.prevRune < 0 {
return errors.New("strings.Reader: previous operation was not ReadRune")
コアとなるコードの解説
上記の差分は、src/pkg/strings/reader.go
ファイルから以下の3つのメソッドのコメントが削除されたことを示しています。
-
UnreadByte()
メソッドのコメント削除:// UnreadByte moves the reading position back by one byte. // It is an error to call UnreadByte if nothing has been // read yet.
UnreadByte
はio.ByteScanner
インターフェース(ReadByte
とUnreadByte
を持つ)の一部として期待される機能です。このコメントは、メソッドの基本的な動作とエラー条件を説明していましたが、io.ByteScanner
インターフェースのドキュメントで同様の情報が提供されるため、冗長と判断されました。 -
ReadRune()
メソッドのコメント削除:// ReadRune reads and returns the next UTF-8-encoded // Unicode code point from the buffer. // If no bytes are available, the error returned is io.EOF. // If the bytes are an erroneous UTF-8 encoding, it // consumes one byte and returns U+FFFD, 1.
ReadRune
はio.RuneReader
インターフェースの主要なメソッドです。このコメントは、メソッドの目的、EOF処理、不正なUTF-8エンコーディングの処理について詳細に説明していました。しかし、これらの情報はio.RuneReader
インターフェースのドキュメントでカバーされるべき内容であり、strings.Reader
の実装固有のコメントとしては過剰と見なされました。 -
UnreadRune()
メソッドのコメント削除:// UnreadRune causes the next call to ReadRune to return the same rune // as the previous call to ReadRune. // The last method called on r must have been ReadRune.
UnreadRune
はio.RuneScanner
インターフェース(ReadRune
とUnreadRune
を持つ)の一部として期待される機能です。このコメントも、メソッドの基本的な動作と前提条件を説明していましたが、io.RuneScanner
インターフェースのドキュメントで同様の情報が提供されるため、削除されました。
これらのコメントの削除は、Goのドキュメンテーション慣習に従い、インターフェースによって提供される機能のドキュメントはインターフェース自体に集約し、実装側のコメントは実装固有の振る舞いや注意点に限定するという原則を徹底するためのものです。これにより、コードの重複が減り、ドキュメンテーションの一貫性が向上します。
関連リンク
- Go issue #2957: https://github.com/golang/go/issues/2957
- Go CL 5653053: https://golang.org/cl/5653053
参考にした情報源リンク
- Go Documentation Conventions: https://go.dev/doc/effective_go#commentary
- Go Interfaces: https://go.dev/tour/methods/10
io.ByteReader
documentation: https://pkg.go.dev/io#ByteReaderio.RuneReader
documentation: https://pkg.go.dev/io#RuneReaderio.ByteScanner
documentation: https://pkg.go.dev/io#ByteScannerio.RuneScanner
documentation: https://pkg.go.dev/io#RuneScanner