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

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

このコミットは、Go言語の標準ライブラリであるnet/httpパッケージのドキュメンテーションファイル(doc.go)における記述の修正です。具体的には、http.NewRequest関数の使用例が、その関数の正しいシグネチャ(戻り値)を反映するように更新されました。これにより、ドキュメンテーションがより正確になり、ユーザーがhttp.NewRequestを使用する際にエラーハンドリングを適切に行うことの重要性を示す形となりました。

コミット

  • コミットハッシュ: 2a6b4e120a6f67d532f698f238547690bc18efba
  • 作者: Christoph Hack christoph@tux21b.org
  • コミット日時: 2012年1月19日 木曜日 06:11:02 -0800
  • コミットメッセージ:
    net/http: the documentation should call NewRequest with the right signature.
    
    R=golang-dev, dsymonds
    CC=golang-dev
    https://golang.org/cl/5554063
    

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

https://github.com/golang/go/commit/2a6b4e120a6f67d532f698f238547690bc18efba

元コミット内容

net/httpパッケージのドキュメンテーションにおいて、http.NewRequest関数の呼び出しが正しいシグネチャ(戻り値)で記述されるべきであるという修正。

変更の背景

Go言語では、多くの関数が処理結果とエラーの2つの値を戻り値として返すという慣習があります。これは、エラーが発生しうる操作において、呼び出し元がエラーの有無を明示的にチェックし、適切に処理することを促すための設計思想です。

http.NewRequest関数も例外ではなく、HTTPリクエストオブジェクト(*http.Request)とエラー(error)の2つの値を返します。エラーは、例えば提供されたURLが不正である場合などに発生する可能性があります。

このコミット以前のnet/http/doc.go内のhttp.NewRequestの使用例は、エラーの戻り値を無視し、リクエストオブジェクトのみを受け取る形式で記述されていました。これは、Go言語のエラーハンドリングのベストプラクティスに反しており、ドキュメンテーションとして不正確でした。

この変更の背景には、Go言語の設計原則である「エラーは明示的に処理されるべきである」という考え方があり、公式ドキュメンテーションがその原則を正しく反映しているべきだという認識があります。特に、Go 1.0のリリースが間近に迫っていた時期(このコミットは2012年1月)であり、標準ライブラリのドキュメンテーションの正確性を高めることが重要視されていました。

前提知識の解説

Go言語におけるエラーハンドリング

Go言語では、例外処理のメカニズム(try-catchなど)は存在せず、代わりに多値戻り値(multiple return values)を用いてエラーを扱います。関数がエラーを返す可能性がある場合、通常は最後の戻り値として組み込みのerrorインターフェース型の値を返します。

func someOperation() (ResultType, error) {
    // ... 処理 ...
    if anErrorOccurred {
        return defaultValue, errors.New("something went wrong")
    }
    return actualResult, nil
}

関数を呼び出す側は、以下のようにif err != nilという慣用句を使ってエラーの有無をチェックし、エラーが発生した場合は適切な処理を行います。

result, err := someOperation()
if err != nil {
    // エラー処理
    log.Fatalf("Error: %v", err)
}
// 正常な処理
fmt.Println(result)

このアプローチは、エラー処理を強制し、開発者がエラーを無視することを困難にすることで、より堅牢なコードを書くことを促します。

net/httpパッケージ

net/httpパッケージは、Go言語でHTTPクライアントおよびサーバーを構築するための標準ライブラリです。このパッケージは、HTTPプロトコルの低レベルな詳細を抽象化し、開発者が簡単にHTTPリクエストの送信やレスポンスの処理を行えるようにします。

主要なコンポーネントには以下のようなものがあります。

  • http.Client: HTTPリクエストを送信するためのクライアント。
  • http.Request: 送信するHTTPリクエストを表す構造体。メソッド、URL、ヘッダー、ボディなどを含む。
  • http.Response: 受信したHTTPレスポンスを表す構造体。ステータスコード、ヘッダー、ボディなどを含む。
  • http.NewRequest: http.Requestオブジェクトを生成するための関数。

http.NewRequest関数

http.NewRequest関数は、HTTPリクエストを表現する*http.Request型のインスタンスを生成するために使用されます。そのシグネチャは以下の通りです(コミット当時のGo 1.0 RC6のドキュメントに基づく)。

func NewRequest(method, urlStr string, body io.Reader) (*Request, error)
  • method: HTTPメソッド(例: "GET", "POST", "PUT"など)。
  • urlStr: リクエストのURLを表す文字列。
  • body: リクエストボディのデータを提供するio.Readerインターフェース。ボディがない場合はnilを指定します。

この関数は、*http.Requesterrorの2つの値を返します。errornilでない場合、リクエストの生成中に問題が発生したことを意味します(例: urlStrが不正な形式である場合など)。

doc.goファイル

Go言語のパッケージでは、パッケージ全体のドキュメンテーションを記述するために慣習的にdoc.goというファイルが使用されます。このファイルには、パッケージの目的、使用方法、主要な型や関数の概要などが記述され、go docコマンドやGoの公式ドキュメンテーションサイト(pkg.go.devなど)で参照されます。このコミットは、まさにこのdoc.goファイル内のコード例を修正するものです。

技術的詳細

このコミットの技術的なポイントは、Go言語におけるエラーハンドリングの厳密性と、それがドキュメンテーションにも反映されるべきであるという点に集約されます。

http.NewRequest関数がエラーを返すのは、主にurlStr引数のパースに失敗した場合です。例えば、urlStrがRFC 3986に準拠しない不正な形式であったり、スキーマが欠落していたりする場合にエラーが返されます。このようなエラーは、リクエストオブジェクトが正しく構築できないことを意味するため、呼び出し元は必ずこのエラーをチェックし、適切なフォールバック処理やエラー報告を行う必要があります。

コミット当時のGo言語はまだバージョン1.0のリリース前であり、言語仕様や標準ライブラリのAPIが固まりつつある段階でした。この時期には、Goのエラーハンドリングの哲学が確立され、そのベストプラクティスがコード例やドキュメンテーションにも徹底されるよう、多くの修正が行われました。このコミットもその一環であり、ドキュメンテーションのコード例が、実際のAPIの振る舞いとGoのエラーハンドリングの慣習を正確に反映するように修正されたものです。

具体的には、req := http.NewRequest(...)という記述は、http.NewRequestが返す可能性のあるエラーを完全に無視しています。これは、もしURLのパースに失敗した場合でも、req変数にはnilが代入され、その後のreq.Header.Add(...)client.Do(req)といった操作でパニック(ランタイムエラー)が発生する可能性がありました。

修正後のreq, err := http.NewRequest(...)という記述は、http.NewRequestが返す2つの戻り値(リクエストオブジェクトとエラー)を適切に受け取っています。そして、その後の// ...というコメントは、Go言語の慣習に従い、ここでif err != nil { ... }のようなエラーチェックと処理を行うべきであることを示唆しています。これにより、ドキュメンテーションのコード例が、より堅牢で安全なGoコードの書き方を示唆するようになりました。

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

変更はsrc/pkg/net/http/doc.goファイルに対して行われました。

--- a/src/pkg/net/http/doc.go
+++ b/src/pkg/net/http/doc.go
@@ -34,7 +34,8 @@ settings, create a Client:
 	resp, err := client.Get("http://example.com")
 	// ...
 
-	req := http.NewRequest("GET", "http://example.com", nil)
+	req, err := http.NewRequest("GET", "http://example.com", nil)
+	// ...
 	req.Header.Add("If-None-Match", `W/\"wyzzy\"`)
 	resp, err := client.Do(req)
 	// ...

コアとなるコードの解説

このコミットにおけるコアとなるコードの変更は、src/pkg/net/http/doc.go内の以下の1行の修正と1行の追加です。

  1. 変更前:

    req := http.NewRequest("GET", "http://example.com", nil)
    

    この行では、http.NewRequestが返す2つの戻り値のうち、最初の値(*http.Request)のみをreq変数に代入し、2番目の値(error)を完全に無視していました。これは、Go言語のエラーハンドリングの慣習に反する記述です。

  2. 変更後:

    req, err := http.NewRequest("GET", "http.com", nil)
    // ...
    
    • req, err := http.NewRequest("GET", "http://example.com", nil): この行では、http.NewRequestが返す2つの戻り値(*http.Requesterror)をそれぞれreqerrという変数に代入しています。これにより、err変数を介してエラーの有無をチェックできるようになります。
    • // ...: このコメントは、Go言語のコード例でよく見られるもので、この行の直後にエラーチェックのロジック(if err != nil { ... })が続くべきであることを示唆しています。ドキュメンテーションの簡潔さを保ちつつ、読者に対して適切なエラーハンドリングの必要性を伝えています。

この修正により、net/httpパッケージの公式ドキュメンテーションのコード例が、Go言語のベストプラクティスである「エラーは明示的に処理する」という原則に準拠するようになりました。これは、Go言語の学習者や利用者が、より堅牢で安全なHTTPクライアントコードを書くための正しい手本となります。

関連リンク

参考にした情報源リンク