[インデックス 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つの要素から構成されるタプルとして表現されます。
- 具象型 (concrete type): インターフェース値が現在保持している具象値の型。
- 具象値 (concrete value): インターフェース値が現在保持している具象値そのもの。
nil
インターフェースとnil
具象型
Goにおいて、インターフェース値がnil
であると判断されるのは、その具象型と具象値の両方がnil
である場合のみです。
ここで重要なのが、「nil
の具象型がインターフェースに代入された場合」の挙動です。例えば、*MyError
というポインタ型があり、その値がnil
であるとします。このnil
の*MyError
をerror
インターフェース型に代入すると、インターフェースは以下のようになります。
- 具象型:
*MyError
(これはnil
ではない型情報) - 具象値:
nil
(ポインタの値はnil
)
この場合、インターフェースの具象型がnil
ではないため、インターフェース値全体としてはnil
ではないと判断されます。つまり、if err != nil
のようなチェックを行った場合、err
がnil
ではないと評価されてしまい、予期せぬ動作を引き起こす可能性があります。
この挙動は、特にエラーハンドリングにおいて問題となります。関数がカスタムエラー型のポインタを返し、そのポインタがnil
であるにもかかわらず、それをerror
インターフェースとして返すと、呼び出し元でif err != nil
がtrue
となり、エラーが存在すると誤認されることがあります。
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
挙動による問題が発生しないという特殊な状況を説明しています。しかし、一般的なケースでは具象型を返すことは避けるべきであるという警告の重要性は変わりません。
関連リンク
- Go FAQ - Why is my nil error value not equal to nil? (Go FAQの「nil error」に関するセクション): https://go.dev/doc/go_faq.html#nil_error
参考にした情報源リンク
- Go FAQ - Why is my nil error value not equal to nil?: https://go.dev/doc/go_faq.html#nil_error
- Stack Overflow: Why is a nil error value not equal to nil in Go?: https://stackoverflow.com/questions/13482701/why-is-a-nil-error-value-not-equal-to-nil-in-go
- The Go Programming Language Specification - Interface types: https://go.dev/ref/spec#Interface_types
- Go by Example: Errors: https://gobyexample.com/errors