Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

[インデックス 10698] ファイルの概要

このコミットは、Go言語の標準ライブラリ net/http パッケージ内のサンプルコードにおける軽微な修正です。具体的には、log.Fatal 関数に渡すエラーオブジェクトのメソッドを err.String() から err.Error() へと変更しています。これは、エラーインターフェースの標準的な利用方法に準拠し、より適切なエラーメッセージの出力を行うための修正です。

コミット

  • コミットハッシュ: 3308891c9db7aa453eacb21225319a16e747e1d2
  • Author: Olivier Duperray duperray.olivier@gmail.com
  • Date: Sun Dec 11 09:11:57 2011 -0800

GitHub上でのコミットページへのリンク

https://github.com/golang/go/commit/3308891c9db7aa453eacb21225319a16e747e1d2

元コミット内容

    net/http: fix trivial example server
    
    R=golang-dev, r, r
    CC=golang-dev
    https://golang.org/cl/5479061

変更の背景

この変更は、net/http パッケージ内のコメントアウトされたサンプルコード(ListenAndServe 関数のドキュメントコメント内にある)におけるエラーハンドリングの記述を修正するものです。元々のコードではエラーオブジェクトを文字列として扱うために err.String() を使用していましたが、Go言語のエラーハンドリングの慣習として、エラーインターフェースが提供する Error() メソッドを使用することが推奨されています。この修正は、サンプルコードがGoのエラーハンドリングのベストプラクティスに従うようにするための、些細ながらも重要な改善です。

前提知識の解説

Go言語のエラーハンドリング

Go言語では、エラーは組み込みの error インターフェースによって表現されます。このインターフェースは非常にシンプルで、Error() string という単一のメソッドを定義しています。このメソッドは、エラーに関するユーザーフレンドリーな文字列を返します。

type error interface {
    Error() string
}

関数がエラーを返す場合、通常は最後の戻り値として error 型の値を返します。呼び出し元は、返されたエラーが nil でないかどうかをチェックすることで、エラーが発生したかどうかを判断します。

log.Fatal 関数

log パッケージは、Goプログラムのログ出力機能を提供します。log.Fatal 関数は、引数をフォーマットして標準エラー出力に書き込み、その後に os.Exit(1) を呼び出してプログラムを終了させます。これは、回復不可能なエラーが発生した場合にプログラムを即座に停止させるためによく使用されます。

net/http パッケージ

net/http パッケージは、HTTPクライアントとサーバーの実装を提供します。ウェブアプリケーションを構築する上で中心的な役割を果たすパッケージです。http.ListenAndServe 関数は、指定されたアドレスでHTTPサーバーを起動し、リクエストを処理するためのハンドラを設定します。

String() メソッドと Error() メソッド

Go言語では、任意の型に String() string メソッドを定義することで、その型の値を文字列として表現する方法をカスタマイズできます。これは、fmt パッケージのフォーマット関数(例: fmt.Println)がオブジェクトを文字列に変換する際に使用されます。

しかし、エラーハンドリングの文脈では、error インターフェースの Error() string メソッドが標準的なエラーメッセージの取得方法です。Error() メソッドは、エラーの性質を説明する文字列を返すことを目的としています。

err.String() が存在する場合でも、error インターフェースを満たすオブジェクトに対しては err.Error() を呼び出すのが慣習であり、推奨される方法です。これは、error インターフェースのセマンティクスに合致し、コードの意図を明確にするためです。

技術的詳細

このコミットの技術的な核心は、Go言語におけるエラーインターフェースの適切な利用方法にあります。

元のコードでは、ListenAndServe 関数が返す error 型の変数 err に対して err.String() を呼び出していました。これは、error 型が暗黙的に String() メソッドを持つことを期待しているか、あるいは error 型が実際に String() メソッドを持つ具体的な型(例えば、fmt.Errorf で作成されたエラーや、カスタムエラー型)であると仮定している可能性があります。

しかし、Goのエラーハンドリングの標準的なアプローチは、error インターフェースが提供する Error() メソッドを使用することです。Error() メソッドは、error インターフェースを実装するすべての型が必ず持つことが保証されているため、より堅牢で汎用的なエラーメッセージの取得方法となります。

この修正は、サンプルコードがGoのエラーハンドリングのベストプラクティスに準拠するようにするためのものです。err.String() がたまたま動作していたとしても、err.Error() を使用することで、コードの可読性と保守性が向上し、将来的な互換性の問題を防ぐことができます。特に、error インターフェースを実装する様々なカスタムエラー型や、標準ライブラリのエラー型が返される可能性がある場合、Error() メソッドを使用することが一貫性のあるアプローチとなります。

コアとなるコードの変更箇所

--- a/src/pkg/net/http/server.go
+++ b/src/pkg/net/http/server.go
@@ -1027,7 +1027,7 @@ func (srv *Server) Serve(l net.Listener) error {
 //		http.HandleFunc("/hello", HelloServer)
 //		err := http.ListenAndServe(":12345", nil)
 //		if err != nil {
-//			log.Fatal("ListenAndServe: ", err.String())
+//			log.Fatal("ListenAndServe: ", err.Error())
 //		}
 //	}
 func ListenAndServe(addr string, handler Handler) error {

コアとなるコードの解説

変更は src/pkg/net/http/server.go ファイルの1029行目にあるコメントアウトされたサンプルコード内で行われています。

  • 変更前:

    //			log.Fatal("ListenAndServe: ", err.String())
    

    ここでは、ListenAndServe 関数が返したエラー err に対して String() メソッドを呼び出し、その結果を log.Fatal に渡していました。

  • 変更後:

    //			log.Fatal("ListenAndServe: ", err.Error())
    

    変更後では、err に対して Error() メソッドを呼び出しています。これは、Go言語の error インターフェースが定義する標準的なメソッドであり、エラーメッセージを取得するための正しい方法です。

この修正により、サンプルコードはGoのエラーハンドリングの慣習に沿ったものとなり、より堅牢で意図が明確なコードになりました。

関連リンク

参考にした情報源リンク

  • Go言語の公式ドキュメント
  • Go言語のエラーハンドリングに関する一般的な慣習とベストプラクティス
  • Go言語の fmt パッケージにおける String() メソッドの利用に関する情報