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

[インデックス 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 {})。このようなループは、通常、プログラムが特定の条件を満たすまで継続的に処理を行うデーモンやサーバーなどで使用されます。無限ループの内部でreturnbreakpanicなどがない限り、そのループから抜け出すことはありません。
  • if-elseステートメント: if-elseステートメントは、条件に基づいて異なるコードブロックを実行するための制御構造です。両方のブランチ(ifelse)が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」セクションです。

  1. 既存のTODOコメントの削除: 以前のバージョンでは、このセクションにTODOというプレースホルダーがありましたが、これが削除されました。
  2. Go 1.1以前の挙動の説明:
    • Go 1.1以前では、値を返す関数は末尾に明示的なreturnまたはpanicが必要であったことが説明されています。
    • これはプログラマに関数の意味を明確にさせるためのシンプルな方法であったと述べられています。
    • しかし、無限forループのみを含む関数など、最終的なreturnが明らかに不要なケースが多数存在したことが指摘されています。
  3. Go 1.1での新しいルールの導入:
    • Go 1.1では、最終return文に関するルールがより寛容になったことが説明されています。
    • 「終端ステートメント(terminating statement)」の概念が導入されたことが強調され、その定義(関数が実行する最後のステートメントであることが保証されるもの)が示されています。
    • 終端ステートメントの例として、「条件なしのforループ」や「両方の半分がreturnで終わるif-elseステートメント」が挙げられています。
    • 関数の最後のステートメントが構文的に終端ステートメントであることが示される場合、最終return文は不要であると明記されています。
  4. ルールの性質に関する注意:
    • このルールが純粋に構文的であり、コード内の値に注意を払わず、複雑な分析を必要としないことが強調されています。
  5. 更新に関するガイダンス:
    • この変更が後方互換性があること、しかし冗長なreturn文やpanic呼び出しを含む既存のコードは手動で簡素化できることが述べられています。
    • go vetツールがそのようなコードを識別できることが示されています。
  6. selectステートメントに関する修正:
    • reflectパッケージを使用してselectステートメントを実行できるようになったという記述で、selectが引用符で囲まれていなかった部分が修正され、"select"と正しく表示されるようになりました。これは小さな修正ですが、ドキュメントの正確性を向上させます。

この追加されたドキュメントは、Go 1.1の重要な言語変更の一つであるreturn要件の緩和について、その背景、新しいルール、および開発者が既存のコードをどのように扱うべきかについて明確な指針を提供しています。

関連リンク

参考にした情報源リンク

  • コミット情報: /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