[インデックス 17803] ファイルの概要
このコミットは、Go言語の公式ドキュメントである doc/effective_go.html
内のコード例の修正に関するものです。具体的には、switch
ステートメントの誤った使用例を修正し、より正確なGo言語のイディオムに合致させることを目的としています。
コミット
commit 244014e40212a3790ebdc2b18ee3875262cced51
Author: Shenghou Ma <minux.ma@gmail.com>
Date: Tue Oct 15 21:30:49 2013 -0400
doc/effective_go.html: fix code example
Fixes #6595.
R=golang-dev, adg
CC=golang-dev
https://golang.org/cl/14425062
GitHub上でのコミットページへのリンク
https://github.com/golang/go/commit/244014e40212a3790ebdc2b18ee3875262cced51
元コミット内容
doc/effective_go.html: fix code example
Fixes #6595.
R=golang-dev, adg
CC=golang-dev
https://golang.org/cl/14425062
変更の背景
このコミットは、Go言語の公式ドキュメント「Effective Go」内のコード例に存在する論理的な誤り、またはGo言語のイディオムにそぐわない記述を修正するために行われました。具体的には、switch
ステートメントの利用方法に関するコード例が、Goの switch
の動作、特に break
ステートメントのスコープに関して誤解を招く可能性があったため、これを修正する必要がありました。
Go言語の switch
ステートメントは、他のC系の言語とは異なり、case
の最後に break
を明示的に記述する必要がありません。各 case
は暗黙的に break
を含んでいます。しかし、for
ループなどの外側の構造から抜け出すために break
を使用する場合、ラベル付き break
を使用する必要があります。元のコード例では、switch
の内部で break
が使用されており、これが switch
から抜けるのか、それとも外側の for
ループから抜けるのかが不明瞭でした。この修正は、switch
ステートメントを導入することで、break
が switch
のみを対象とすることを明確にし、コードの意図をより正確に伝えることを目的としています。
前提知識の解説
Go言語の switch
ステートメント
Go言語の switch
ステートメントは、他の多くのプログラミング言語とは異なる特徴を持っています。
- 暗黙的な
break
: Goのswitch
では、各case
ブロックの最後にbreak
ステートメントを明示的に記述する必要がありません。case
がマッチすると、そのブロックが実行された後、自動的にswitch
ステートメント全体から抜けます。これは「fallthrough」を防ぐための設計であり、C/C++などの言語でbreak
を忘れることによるバグを防ぎます。明示的に次のcase
に進みたい場合はfallthrough
キーワードを使用します。 - 式なし
switch
(Type Switch / Expressionless Switch):switch
キーワードの後に式を記述しない場合、それはswitch true
と同等に扱われます。この形式は、複数の条件を評価し、最初にtrue
と評価されたcase
ブロックを実行するのに非常に便利です。これは、他の言語のif-else if-else
チェーンのより簡潔な代替手段としてよく使用されます。 case
の複数値:case
にはカンマ区切りで複数の値を指定できます。default
ケース: どのcase
にもマッチしない場合に実行されるdefault
ケースをオプションで指定できます。default
は任意の場所に配置できますが、通常は最後に置かれます。
ラベル付き break
と continue
Go言語では、for
ループや switch
ステートメントなどの制御構造にラベルを付けることができます。これにより、break
や continue
ステートメントがどのループや switch
を対象とするかを明示的に指定できます。
break Label
: 指定されたLabel
の付いたfor
、switch
、またはselect
ステートメントから抜け出します。continue Label
: 指定されたLabel
の付いたfor
ループの次のイテレーションに進みます。
この機能は、ネストされたループから一度に抜け出したい場合や、特定の外側のループの次のイテレーションに進みたい場合に特に役立ちます。
Effective Go
ドキュメント
Effective Go
は、Go言語の公式ドキュメントの一部であり、Go言語を効果的に記述するためのヒントやイディオム、ベストプラクティスを提供しています。Go言語の設計思想や、Goらしいコードの書き方を学ぶ上で非常に重要なリソースです。このドキュメント内のコード例は、Go言語の正しい使い方を示すための規範となるため、その正確性は非常に重要です。
技術的詳細
このコミットの技術的な詳細を理解するためには、Go言語の switch
ステートメントの動作と、ラベル付き break
の挙動を正確に把握する必要があります。
元のコードは以下のようでした。
Loop:
for n := 0; n < len(src); n += size {
case src[n] < sizeOne: // これは構文エラーではないが、switchのコンテキスト外
if validateOnly {
break
}
// ...
// ...
}
この元のコードは、for
ループの直下に case
が記述されており、これはGo言語の構文として不正です。case
は switch
または select
ステートメントの内部でのみ使用できます。このコミットは、この構文エラーを修正し、case
を適切な switch
ブロック内に配置することで、コードの意図を明確にしています。
修正後のコードは以下のようになります。
Loop:
for n := 0; n < len(src); n += size {
switch { // 式なしswitch
case src[n] < sizeOne:
if validateOnly {
break // このbreakはswitchステートメントから抜ける
}
// ...
// ...
} // switchブロックの終わり
}
この変更により、以下の点が明確になります。
switch
の導入:for
ループの内部にswitch
ステートメントが導入されました。これにより、case
が適切なコンテキストで評価されるようになります。- 式なし
switch
:switch
の後に式が記述されていないため、これはswitch true
と同等に扱われます。各case
の条件式がtrue
と評価された場合にそのブロックが実行されます。 break
のスコープ:switch
ブロック内のbreak
ステートメントは、そのswitch
ステートメントからのみ抜け出します。外側のfor
ループから抜け出すためには、break Loop
のようにラベル付きbreak
を使用する必要があります。元のコードではswitch
が存在しなかったため、break
がfor
ループから抜け出すことを意図していた可能性がありましたが、構文的に誤っていました。修正により、break
の意図がswitch
からの脱出であることが明確になりました。
この修正は、Go言語の switch
ステートメントの正しい使用方法と、break
のスコープに関する理解を深める上で非常に重要です。Effective Go
ドキュメントの目的は、Go言語の正しいイディオムを示すことであるため、このような構文エラーや誤解を招く可能性のあるコード例は修正されるべきです。
コアとなるコードの変更箇所
--- a/doc/effective_go.html
+++ b/doc/effective_go.html
@@ -795,6 +795,7 @@ This example shows both uses.
<pre>
Loop:
for n := 0; n < len(src); n += size {
+ switch {
case src[n] < sizeOne:
if validateOnly {
break
コアとなるコードの解説
変更は doc/effective_go.html
ファイルの795行目付近に集中しています。
+ switch {
: この行が追加された主要な変更点です。既存のfor
ループの内部に、式なしのswitch
ステートメントが導入されました。これにより、その後のcase
ステートメントが有効な構文コンテキスト内で評価されるようになります。式なしswitch
は、複数の条件を評価し、最初に真となるcase
を実行するGoの一般的なイディオムです。
この修正により、元のコード例が抱えていた構文エラーが解消され、break
ステートメントのスコープが switch
ブロック内に限定されることが明確になりました。これは、Go言語の switch
の動作と、ラベル付き break
の必要性を正確に反映した変更です。
関連リンク
- Go言語の公式ドキュメント: https://golang.org/doc/
- Effective Go: https://golang.org/doc/effective_go.html
- Go言語の
switch
ステートメントに関する公式ドキュメント: https://golang.org/ref/spec#Switch_statements - Go言語の
break
ステートメントに関する公式ドキュメント: https://golang.org/ref/spec#Break_statements - 関連するGo issue: https://github.com/golang/go/issues/6595
- Go CL (Code Review): https://golang.org/cl/14425062
参考にした情報源リンク
- Go言語の公式ドキュメント
- GitHubのコミット履歴
- Go言語のコードレビューシステム (Gerrit)
- Go言語のIssueトラッカー
- Go言語の
switch
ステートメントとbreak
ステートメントに関する一般的な知識