[インデックス 11360] ファイルの概要
このコミットは、Go言語の標準ライブラリ内の複数のパッケージにおいて、エラー変数の命名規則を FooError
から ErrFoo
へと変更するものです。これは、Go言語におけるエラー命名の慣習に沿ったものであり、コードの一貫性と可読性を向上させることを目的としています。具体的には、archive/tar
、archive/zip
、compress/gzip
、compress/zlib
、crypto/bcrypt
といったパッケージ内のエラー変数が影響を受けています。
コミット
commit 37d2f8190d5477c306675ec17cfc05499630fe63
Author: Brad Fitzpatrick <bradfitz@golang.org>
Date: Tue Jan 24 11:48:48 2012 -0800
rename FooError vars to ErrFoo
R=golang-dev, rsc
CC=golang-dev
https://golang.org/cl/5574056
GitHub上でのコミットページへのリンク
https://github.com/golang/go/commit/37d2f8190d5477c306675ec17cfc05499630fe63
元コミット内容
このコミットの目的は、「FooError」という命名パターンを持つエラー変数を「ErrFoo」という命名パターンに変更することです。これは、Go言語の標準ライブラリ全体でエラー変数の命名規則を統一し、より慣用的なスタイルに合わせるためのリファクタリング作業の一環です。
変更の背景
Go言語では、コードの可読性と一貫性を非常に重視しています。特に、エラーハンドリングはGo言語の設計思想の中心的な部分であり、エラーの命名規則もその一部です。初期のGo言語のコードベースでは、エラー変数の命名に様々なパターンが存在していました。しかし、Goコミュニティと開発チームの間で、エラー変数は Err
プレフィックスを付けて、その後にエラーの種類を示すキャメルケースの名前を続けるという慣習が確立されていきました。
このコミットが行われた2012年頃は、Go言語がまだ比較的新しく、標準ライブラリのAPIや慣習が成熟していく過程にありました。このようなリファクタリングは、言語の進化とともにベストプラクティスが確立され、それらを既存のコードベースに適用していく典型的な例です。FooError
から ErrFoo
への変更は、エラー変数が error
インターフェースを実装する値であることを明確にし、他の変数名との混同を避けるためのものです。これにより、開発者がコードを読んだ際に、その変数がエラー値であることを直感的に理解できるようになります。
前提知識の解説
Go言語におけるエラーハンドリング
Go言語には例外処理の仕組み(try-catchなど)は存在せず、エラーは関数の戻り値として明示的に扱われます。慣習として、エラーを返す関数は最後の戻り値として error
型を返します。error
は組み込みのインターフェースであり、Error() string
メソッドを持ちます。
type error interface {
Error() string
}
errors.New
関数
Go言語の標準ライブラリには errors
パッケージが含まれており、その中の errors.New
関数は、シンプルなエラー値を生成するために使用されます。
func New(text string) error
この関数は、指定された文字列をエラーメッセージとして持つ新しい error
型の値を返します。このコミットで変更されている var
宣言されたエラー変数は、通常、この errors.New
を使って初期化されています。
Go言語の命名規則
Go言語には、変数、関数、型などの命名に関する明確な慣習があります。
- エクスポートされる識別子: パッケージ外からアクセス可能な識別子(関数、変数、型など)は、大文字で始まります。
- エクスポートされない識別子: パッケージ内でのみ使用される識別子は、小文字で始まります。
- エラー変数: 慣習として、エクスポートされるエラー変数は
Err
プレフィックスを付けて、その後にエラーの種類を示すキャメルケースの名前を続けます(例:ErrNotFound
,ErrInvalidParameter
)。これは、その変数がerror
型のインスタンスであることを明確に示し、他の種類の変数と区別しやすくするためです。
このコミットは、まさにこの「エラー変数」の命名慣習に沿った変更を行っています。
技術的詳細
このコミットの技術的な変更は非常にシンプルですが、Go言語の設計思想と慣習を反映しています。
- 命名規則の統一: 既存の
FooError
という形式で宣言されていたエラー変数を、ErrFoo
という形式に一括してリネームしています。例えば、HeaderError
はErrHeader
に、FormatError
はErrFormat
に変更されています。 - 影響範囲: この変更は、
src/pkg/archive/tar
、src/pkg/archive/zip
、src/pkg/compress/gzip
、src/pkg/compress/zlib
、src/pkg/crypto/bcrypt
といった複数の標準ライブラリパッケージにわたっています。これは、Go言語の標準ライブラリ全体で一貫したエラー命名規則を適用しようとする意図を示しています。 - 参照箇所の更新: 変数名が変更されたため、その変数を参照しているすべての箇所(例えば、
if err == HeaderError
のような比較)も新しい変数名 (if err == ErrHeader
) に更新されています。これにより、コンパイルエラーを防ぎ、コードの整合性を保っています。 - テストコードの更新: 関連するテストファイル (
_test.go
ファイル) も、変更されたエラー変数名に合わせて更新されています。これにより、テストが引き続き正しく機能し、リファクタリングによって既存の動作が損なわれていないことを保証しています。
この変更は、機能的な変更を一切伴いません。純粋にコードのスタイルと一貫性を向上させるためのリファクタリングです。しかし、このような一貫性は、大規模なコードベースにおいて開発者がコードを理解し、保守する上で非常に重要となります。
コアとなるコードの変更箇所
src/pkg/archive/tar/reader.go
における変更を例として示します。
--- a/src/pkg/archive/tar/reader.go
+++ b/src/pkg/archive/tar/reader.go
@@ -18,7 +18,7 @@ import (
)
var (
- HeaderError = errors.New("invalid tar header")
+ ErrHeader = errors.New("invalid tar header")
)
// A Reader provides sequential access to the contents of a tar archive.
@@ -123,13 +123,13 @@ func (tr *Reader) readHeader() *Header {
if bytes.Equal(header, zeroBlock[0:blockSize]) {
tr.err = io.EOF
} else {
- tr.err = HeaderError // zero block and then non-zero block
+ tr.err = ErrHeader // zero block and then non-zero block
}
return nil
}
if !tr.verifyChecksum(header) {
- tr.err = HeaderError
+ tr.err = ErrHeader
return nil
}
@@ -188,7 +188,7 @@ func (tr *Reader) readHeader() *Header {
}
if tr.err != nil {
- tr.err = HeaderError
+ tr.err = ErrHeader
return nil
}
コアとなるコードの解説
上記の差分は、archive/tar
パッケージ内の reader.go
ファイルにおける変更を示しています。
-
エラー変数の宣言:
- HeaderError = errors.New("invalid tar header") + ErrHeader = errors.New("invalid tar header")
ここで、
HeaderError
という名前で宣言されていたerror
型の変数がErrHeader
に変更されています。errors.New
関数を使って「invalid tar header」というメッセージを持つ新しいエラー値が作成され、この変数に割り当てられています。この変更は、Go言語のエラー命名慣習 (Err
プレフィックス) に従うものです。 -
エラー変数の参照箇所の更新:
- tr.err = HeaderError // zero block and then non-zero block + tr.err = ErrHeader // zero block and then non-zero block
- tr.err = HeaderError + tr.err = ErrHeader
- tr.err = HeaderError + tr.err = ErrHeader
Reader
型のメソッド内で、以前HeaderError
を使用してエラーを割り当てていたすべての箇所が、新しい変数名ErrHeader
に更新されています。これは、変数名のリネームに伴う必須の変更であり、コードの機能には影響を与えません。
同様の変更が、archive/zip
、compress/gzip
、compress/zlib
、crypto/bcrypt
の各パッケージ内の関連ファイルでも行われています。例えば、zip
パッケージでは FormatError
が ErrFormat
に、UnsupportedMethod
が ErrAlgorithm
に、ChecksumError
が ErrChecksum
に変更されています。bcrypt
パッケージでは MismatchedHashAndPasswordError
が ErrMismatchedHashAndPassword
に、HashTooShortError
が ErrHashTooShort
に変更されています。
これらの変更は、Go言語の標準ライブラリ全体でエラー変数の命名規則を統一し、コードベースの一貫性と可読性を高めるための重要なステップでした。
関連リンク
- Go言語の公式ドキュメント: https://go.dev/
- Go言語のエラーハンドリングに関する公式ブログ記事 (より新しい情報): https://go.dev/blog/error-handling-and-go
- Go言語のコードレビューコメントの慣習 (Naming Errorsセクション): https://go.dev/wiki/CodeReviewComments#naming-errors
参考にした情報源リンク
- コミット情報:
/home/orange/Project/comemo/commit_data/11360.txt
- GitHubコミットページ: https://github.com/golang/go/commit/37d2f8190d5477c306675ec17cfc05499630fe63
- Go言語の
errors
パッケージドキュメント: https://pkg.go.dev/errors - Go言語の
archive/tar
パッケージドキュメント: https://pkg.go.dev/archive/tar - Go言語の
archive/zip
パッケージドキュメント: https://pkg.go.dev/archive/zip - Go言語の
compress/gzip
パッケージドキュメント: https://pkg.go.dev/compress/gzip - Go言語の
compress/zlib
パッケージドキュメント: https://pkg.go.dev/compress/zlib - Go言語の
crypto/bcrypt
パッケージドキュメント: https://pkg.go.dev/crypto/bcrypt - Go言語の命名規則に関する一般的な情報 (Stack Overflowなど): https://stackoverflow.com/questions/tagged/go-naming-conventions (一般的な情報源として参照)