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

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

このコミットは、Go言語のドキュメント doc/articles/error_handling.html において、エラーハンドリングに関する記述を修正し、特定の警告(具象型のエラーを返すことの危険性)についてGo FAQへの参照を追加するものです。これにより、読者がより深くこの概念を理解できるようになります。

コミット

commit f00872527b9e31cf3389ef49788b21b22b1a51da
Author: Stefan Nilsson <snilsson@nada.kth.se>
Date:   Thu Mar 15 09:15:16 2012 +1100

    doc: add reference to FAQ to explain warning about concrete type
    
    R=golang-dev, adg
    CC=golang-dev
    https://golang.org/cl/5820048

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

https://github.com/golang/go/commit/f00872527b9e31cf3389ef49788b21b22b1a51da

元コミット内容

doc: add reference to FAQ to explain warning about concrete type

R=golang-dev, adg
CC=golang-dev
https://golang.org/cl/5820048

変更の背景

Go言語のエラーハンドリングに関するドキュメント doc/articles/error_handling.html には、「具象型のエラーを返すことは通常間違いである」という警告が記載されていました。しかし、その理由については「別の記事で議論される」とだけ書かれており、読者にとっては不親切な状態でした。

このコミットの背景には、この警告の重要性を強調し、その理由を明確にする必要性がありました。特に、Go言語におけるインターフェースとnilの挙動は、初心者にとって混乱しやすいポイントであり、nilの具象型がnilではないインターフェース値になるという「nil error concrete type」の問題は、予期せぬバグを引き起こす可能性があります。

この変更は、読者がエラーハンドリングのベストプラクティスを理解し、一般的な落とし穴を避けるための手助けをすることを目的としています。Go FAQに既存の解説があるため、そこへの直接的なリンクを追加することで、ドキュメントの整合性を保ちつつ、読者に詳細な情報を提供できるようになりました。

前提知識の解説

このコミットを理解するためには、Go言語におけるインターフェースとnilの挙動に関する以下の前提知識が必要です。

Go言語におけるインターフェース

Go言語のインターフェースは、メソッドのセットを定義する型です。変数がインターフェース型を持つ場合、その変数はそのインターフェースが定義するすべてのメソッドを実装する任意の具象型の値を保持できます。

Goのインターフェース値は、内部的には2つの要素から構成されるタプルとして表現されます。

  1. 具象型 (concrete type): インターフェース値が現在保持している具象値の型。
  2. 具象値 (concrete value): インターフェース値が現在保持している具象値そのもの。

nilインターフェースとnil具象型

Goにおいて、インターフェース値がnilであると判断されるのは、その具象型と具象値の両方がnilである場合のみです。

ここで重要なのが、「nilの具象型がインターフェースに代入された場合」の挙動です。例えば、*MyErrorというポインタ型があり、その値がnilであるとします。このnil*MyErrorerrorインターフェース型に代入すると、インターフェースは以下のようになります。

  • 具象型: *MyError (これはnilではない型情報)
  • 具象値: nil (ポインタの値はnil)

この場合、インターフェースの具象型がnilではないため、インターフェース値全体としてはnilではないと判断されます。つまり、if err != nilのようなチェックを行った場合、errnilではないと評価されてしまい、予期せぬ動作を引き起こす可能性があります。

この挙動は、特にエラーハンドリングにおいて問題となります。関数がカスタムエラー型のポインタを返し、そのポインタがnilであるにもかかわらず、それをerrorインターフェースとして返すと、呼び出し元でif err != niltrueとなり、エラーが存在すると誤認されることがあります。

Goのベストプラクティスでは、エラーを返す関数は常にerrorインターフェース型を返すように推奨されており、具象型を直接返すことは避けるべきとされています。これは、上記のようなnilの挙動による混乱を避けるためです。

技術的詳細

このコミットは、doc/articles/error_handling.html ファイル内の特定の箇所を修正しています。具体的には、エラーハンドリングの例の中で、*appErrorのような具象型を返すことに関する警告文を更新しています。

変更前は、この警告の理由が「別の記事で議論される」と曖昧に書かれていました。

<p>
(It's usually a mistake to pass back the concrete type of an error rather than
<code>error</code>, for reasons to be discussed in another article, but
it's the right thing to do here because <code>ServeHTTP</code> is the only
place that sees the value and uses its contents.)
</p>

このコミットにより、この部分がGo FAQの該当セクションへの直接的なリンクに置き換えられました。

<p>
(It's usually a mistake to pass back the concrete type of an error rather than
<code>error</code>,
for reasons discussed in <a href="/doc/go_faq.html#nil_error">the Go FAQ</a>,
but it's the right thing to do here because <code>ServeHTTP</code> is the only
place that sees the value and uses its contents.)
</p>

これにより、読者は「具象型のエラーを返すことがなぜ間違いなのか」という疑問に対して、Go FAQの「nil error」に関する詳細な説明をすぐに参照できるようになりました。Go FAQの当該セクションでは、インターフェースの内部表現と、nilの具象型がnilではないインターフェース値になるという挙動について解説されています。

この変更は、ドキュメントの正確性と利便性を向上させ、Go言語のエラーハンドリングに関する一般的な誤解を解消するのに役立ちます。

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

--- a/doc/articles/error_handling.html
+++ b/doc/articles/error_handling.html
@@ -258,8 +258,9 @@ Next we modify the appHandler type to return <code>*appError</code> values:\n 
 <p>\n (It's usually a mistake to pass back the concrete type of an error rather than\n-<code>error</code>, for reasons to be discussed in another article, but\n-it's the right thing to do here because <code>ServeHTTP</code> is the only\n+<code>error</code>,\n+for reasons discussed in <a href="/doc/go_faq.html#nil_error">the Go FAQ</a>,\n+but it's the right thing to do here because <code>ServeHTTP</code> is the only\n place that sees the value and uses its contents.)\n </p>\n 

コアとなるコードの解説

上記の差分は、doc/articles/error_handling.html ファイル内のHTMLコードの変更を示しています。

  • - で始まる行は削除された行です。
  • + で始まる行は追加された行です。

変更前は以下の記述がありました。

<code>error</code>, for reasons to be discussed in another article, but
it's the right thing to do here because <code>ServeHTTP</code> is the only

この部分では、「errorインターフェースではなく具象型を返すことは通常間違いであり、その理由は別の記事で議論される」と述べられていました。

変更後、この部分が以下のように修正されました。

<code>error</code>,
for reasons discussed in <a href="/doc/go_faq.html#nil_error">the Go FAQ</a>,
but it's the right thing to do here because <code>ServeHTTP</code> is the only

ここで注目すべきは、for reasons to be discussed in another article が削除され、代わりに for reasons discussed in <a href="/doc/go_faq.html#nil_error">the Go FAQ</a> が追加された点です。

この変更により、読者は「具象型のエラーを返すことの危険性」について、Go言語の公式FAQの「nil error」セクションに直接誘導されるようになりました。これにより、ドキュメントの記述がより正確かつ網羅的になり、読者が関連情報を探しやすくなりました。

ServeHTTP の文脈で具象型を返すことが「正しいこと」とされているのは、この特定のケースではServeHTTP関数のみがその値を見てその内容を使用するため、インターフェースのnil挙動による問題が発生しないという特殊な状況を説明しています。しかし、一般的なケースでは具象型を返すことは避けるべきであるという警告の重要性は変わりません。

関連リンク

参考にした情報源リンク