[インデックス 15906] ファイルの概要
このコミットは、Go言語のバージョン1.1に関する公式ドキュメントである doc/go1.1.html
ファイルに対する変更です。このファイルは、Go 1.1リリースにおける言語仕様、ライブラリ、ツールなどの主要な変更点や新機能について解説しています。具体的には、関数のreturn
要件に関する新しいルールについて記述が追加されています。
コミット
このコミットは、Go 1.1における関数のreturn
要件の変更について、公式ドキュメントに説明を追加するものです。以前のバージョンでは、値を返す関数は末尾に明示的なreturn
文またはpanic
呼び出しを必要としていましたが、Go 1.1からは「終端ステートメント(terminating statement)」の概念が導入され、構文的に終端することが保証されるステートメントで関数が終了する場合、明示的なreturn
文が不要になりました。
GitHub上でのコミットページへのリンク
https://github.com/golang/go/commit/7191ef7199cae4753dd7f06e66d9b82d760136aa
元コミット内容
commit 7191ef7199cae4753dd7f06e66d9b82d760136aa
Author: Rob Pike <r@golang.org>
Date: Fri Mar 22 14:51:22 2013 -0700
doc/go1.1.html: return requirements
R=golang-dev, rsc, jeremyjackins, gri
CC=golang-dev
https://golang.org/cl/7838045
変更の背景
Go言語の初期バージョンでは、値を返す関数は、その関数の最後に明示的なreturn
文またはpanic
呼び出しを記述する必要がありました。これは、プログラマが関数の意味を明確にするためのシンプルな方法として導入されました。しかし、無限for
ループのみを含む関数など、最終的なreturn
文が明らかに不要なケースが多数存在しました。このような冗長性を解消し、コードの記述をより柔軟にするために、Go 1.1でreturn
要件のルールが緩和されることになりました。このコミットは、その新しいルールを公式ドキュメントに反映させるものです。
前提知識の解説
- Go言語の関数と
return
文: Go言語では、関数は0個以上の値を返すことができます。値を返す関数は、通常、関数の実行を終了し、指定された値を呼び出し元に返すためにreturn
文を使用します。 panic
:panic
は、Goプログラムの通常の実行フローを中断するために使用される組み込み関数です。panic
が呼び出されると、現在の関数の実行が停止し、遅延関数(defer
で登録された関数)が実行され、その後、呼び出し元の関数にパニックが伝播していきます。最終的に、パニックがリカバリされない場合、プログラムは異常終了します。- 無限
for
ループ: Go言語のfor
ループは、条件を指定しない場合、無限ループとなります(例:for {}
)。このようなループは、通常、プログラムが特定の条件を満たすまで継続的に処理を行うデーモンやサーバーなどで使用されます。無限ループの内部でreturn
やbreak
、panic
などがない限り、そのループから抜け出すことはありません。 if-else
ステートメント:if-else
ステートメントは、条件に基づいて異なるコードブロックを実行するための制御構造です。両方のブランチ(if
とelse
)がreturn
文で終了する場合、そのif-else
ステートメント全体が関数を終了させることが保証されます。- 終端ステートメント(Terminating statement): Go 1.1で導入された概念で、Go言語の仕様書で定義されています。これは、そのステートメントが実行されると、そのステートメントを含む関数の実行が必ず終了することを構文的に保証するステートメントを指します。
go vet
:go vet
は、Goプログラムの潜在的なバグや疑わしい構成を報告するツールです。このツールは、コンパイルエラーにはならないが、実行時に問題を引き起こす可能性のあるコードパターンを検出するのに役立ちます。この変更に関連して、go vet
は冗長なreturn
文を識別できるようになりました。
技術的詳細
Go 1.1以前は、値を返す関数は、関数の末尾に明示的なreturn
文またはpanic
呼び出しを必要としていました。これは、コンパイラが関数の実行パスを確実に把握し、値が常に返されることを保証するための一つの方法でした。
Go 1.1では、このルールがより寛容になりました。新しいルールでは、「終端ステートメント(terminating statement)」の概念が導入されています。終端ステートメントとは、そのステートメントが実行されると、そのステートメントを含む関数の実行が必ず終了することを構文的に保証するステートメントです。
具体的には、以下のようなステートメントが終端ステートメントの例として挙げられます。
- 条件なしの
for
ループ:for {}
のような無限ループは、そのループから抜け出すことがないため、関数を終端させます。 - 両方のブランチが
return
で終わるif-else
ステートメント:if condition { return value } else { return otherValue }
のように、if
ブロックとelse
ブロックの両方がreturn
文で終了する場合、このif-else
ステートメント全体が関数を終端させます。
Go 1.1の新しいルールでは、関数の最後のステートメントが構文的に終端ステートメントであることが示される場合、明示的な最終return
文は不要となります。このルールの重要な点は、それが純粋に構文的であるということです。つまり、コード内の値や複雑な実行時分析を必要とせず、コンパイラがコードの構造のみに基づいて判断できることを意味します。これにより、コンパイラの複雑性を増すことなく、プログラマの記述の柔軟性が向上しました。
この変更は後方互換性があります。つまり、Go 1.1以前のコードで冗長なreturn
文やpanic
呼び出しが含まれていても、Go 1.1でコンパイルエラーになることはありません。ただし、go vet
ツールを使用することで、このような冗長なコードを特定し、手動で簡素化することが推奨されています。
コアとなるコードの変更箇所
このコミットは、doc/go1.1.html
ファイルに対して以下の変更を加えています。
--- a/doc/go1.1.html
+++ b/doc/go1.1.html
@@ -54,7 +54,36 @@ TODO
<h3 id="return">Return requirements</h3>
<p>
-TODO
+Before Go 1.1, a function that returned a value needed an explicit "return"
+or call to <code>panic</code> at
+the end of the function; this was a simple way to make the programmer
+be explicit about the meaning of the function. But there are many cases
+where a final "return" is clearly unnecessary, such as a function with
+only an infinite "for" loop.
+</p>
+
+<p>
+In Go 1.1, the rule about final "return" statements is more permissive.
+It introduces the concept of a
+<a href="/ref/spec/#Terminating_statements"><em>terminating statement</em></a>,
+a statement that is guaranteed to be the last one a function executes.
+Examples include
+"for" loops with no condition and "if-else"
+statements in which each half ends in a "return".
+If the final statement of a function can be shown <em>syntactically</em> to
+be a terminating statement, no final "return" statement is needed.
+</p>
+
+<p>
+Note that the rule is purely syntactic: it pays no attention to the values in the
+code and therefore requires no complex analysis.
+</p>
+
+<p>
+<em>Updating</em>: The change is backward-compatible, but existing code
+with superfluous "return" statements and calls to <code>panic</code> may
+be simplified manually.
+Such code can be identified by <code>go vet</code>.
</p>
<h2 id="impl">Changes to the implementations and tools</h2>
@@ -338,7 +367,7 @@ The <a href="/pkg/reflect/"><code>reflect</code></a> package has several signifi
</p>
<p>
-It is now possible to run a <code>select</code> statement using
+It is now possible to run a "select" statement using
the <code>reflect</code> package; see the description of
<a href="/pkg/reflect/#Select"><code>Select</code></a>
and
コアとなるコードの解説
変更の中心は、doc/go1.1.html
内の「Return requirements」セクションです。
- 既存の
TODO
コメントの削除: 以前のバージョンでは、このセクションにTODO
というプレースホルダーがありましたが、これが削除されました。 - Go 1.1以前の挙動の説明:
- Go 1.1以前では、値を返す関数は末尾に明示的な
return
またはpanic
が必要であったことが説明されています。 - これはプログラマに関数の意味を明確にさせるためのシンプルな方法であったと述べられています。
- しかし、無限
for
ループのみを含む関数など、最終的なreturn
が明らかに不要なケースが多数存在したことが指摘されています。
- Go 1.1以前では、値を返す関数は末尾に明示的な
- Go 1.1での新しいルールの導入:
- Go 1.1では、最終
return
文に関するルールがより寛容になったことが説明されています。 - 「終端ステートメント(terminating statement)」の概念が導入されたことが強調され、その定義(関数が実行する最後のステートメントであることが保証されるもの)が示されています。
- 終端ステートメントの例として、「条件なしの
for
ループ」や「両方の半分がreturn
で終わるif-else
ステートメント」が挙げられています。 - 関数の最後のステートメントが構文的に終端ステートメントであることが示される場合、最終
return
文は不要であると明記されています。
- Go 1.1では、最終
- ルールの性質に関する注意:
- このルールが純粋に構文的であり、コード内の値に注意を払わず、複雑な分析を必要としないことが強調されています。
- 更新に関するガイダンス:
- この変更が後方互換性があること、しかし冗長な
return
文やpanic
呼び出しを含む既存のコードは手動で簡素化できることが述べられています。 go vet
ツールがそのようなコードを識別できることが示されています。
- この変更が後方互換性があること、しかし冗長な
select
ステートメントに関する修正:reflect
パッケージを使用してselect
ステートメントを実行できるようになったという記述で、select
が引用符で囲まれていなかった部分が修正され、"select"
と正しく表示されるようになりました。これは小さな修正ですが、ドキュメントの正確性を向上させます。
この追加されたドキュメントは、Go 1.1の重要な言語変更の一つであるreturn
要件の緩和について、その背景、新しいルール、および開発者が既存のコードをどのように扱うべきかについて明確な指針を提供しています。
関連リンク
- Go言語の仕様書における終端ステートメントの定義: https://golang.org/ref/spec/#Terminating_statements
- このコミットのGo Code Review (CL) ページ: https://golang.org/cl/7838045
参考にした情報源リンク
- コミット情報:
/home/orange/Project/comemo/commit_data/15906.txt
- Go言語公式ドキュメント (Go 1.1リリースノート):
doc/go1.1.html
(コミット対象ファイル) - Go言語の仕様書 (Terminating statements): https://golang.org/ref/spec/#Terminating_statements