[インデックス 1851] ファイルの概要
このコミットは、Go言語の公式仕様書である doc/go_spec.html
における switch
ステートメントに関する記述の微調整と明確化を目的としています。特に、switch
ステートメントの文法定義の追加と、fallthrough
キーワードの適用範囲に関する説明の修正が含まれています。
コミット
commit 091cba8d03230545eaa53563d502d94af1f63808
Author: Robert Griesemer <gri@golang.org>
Date: Thu Mar 19 08:39:40 2009 -0700
minor adjustments to switches text
R=r
DELTA=16 (5 added, 1 deleted, 10 changed)
OCL=26530
CL=26543
GitHub上でのコミットページへのリンク
https://github.com/golang/go/commit/091cba8d03230545eaa53563d502d94af1f63808
元コミット内容
minor adjustments to switches text
R=r
DELTA=16 (5 added, 1 deleted, 10 changed)
OCL=26530
CL=26543
変更の背景
このコミットは、Go言語がまだ初期開発段階にあった2009年に行われたものです。当時のGo言語の仕様は活発に定義・洗練されており、言語の挙動を正確かつ曖昧さなく記述することが非常に重要でした。switch
ステートメントは、多くのプログラミング言語に存在する基本的な制御フロー構造ですが、Go言語ではその動作にいくつかの特徴があります。特に、fallthrough
の挙動や、式スイッチと型スイッチの区別は、他の言語からの移行者にとって混乱を招く可能性がありました。
このコミットの目的は、Go言語の switch
ステートメントに関する公式ドキュメントの記述をより明確にし、読者が誤解なくその動作を理解できるようにすることにあります。具体的には、switch
ステートメントの全体的な文法構造を明示的に定義し、fallthrough
キーワードがどの種類の switch
ステートメントに適用されるのかを明確にすることで、仕様の精度を高めています。これは、言語設計者が言語のセマンティクスを厳密に定義しようとする努力の一環です。
前提知識の解説
Go言語の switch
ステートメントを理解するためには、以下の概念を把握しておく必要があります。
-
switch
ステートメントの基本:switch
ステートメントは、与えられた式(または暗黙的にtrue
)の値に基づいて、複数のcase
節の中から一致するものを選択し、そのブロック内のコードを実行する制御フロー構造です。 -
式スイッチ (Expression Switch): これは最も一般的な
switch
の形式で、switch
キーワードの後に式が続きます。各case
節には、その式と比較される値が記述されます。Go言語の式スイッチでは、他のC言語系の言語とは異なり、case
節の最後にbreak
を明示的に書かなくても、一致したcase
節の実行が終了すると自動的にswitch
ステートメント全体から抜けます。 -
型スイッチ (Type Switch): Go言語特有の
switch
の形式で、インターフェース型の変数の動的な型に基づいて処理を分岐させるために使用されます。switch
キーワードの後に変数.(type)
という形式が続きます。各case
節には型が記述され、変数の実際の型がその型と一致する場合に、対応するブロックが実行されます。型スイッチではfallthrough
は使用できません。 -
fallthrough
キーワード: Go言語のswitch
ステートメントは、デフォルトでcase
節の実行後にswitch
から抜けますが、fallthrough
キーワードをcase
節の最後に記述することで、次のcase
節のコードも続けて実行させることができます。これは、C言語などにおける暗黙的なフォールスルーとは異なり、明示的に指定する必要があります。このキーワードは、特定のcase
節の処理が完了した後、追加の処理を次のcase
節で行いたい場合に利用されます。ただし、このコミットで明確化されているように、fallthrough
は式スイッチでのみ有効であり、型スイッチでは使用できません。
これらの概念は、Go言語の制御フローを理解する上で不可欠であり、このコミットが go_spec.html
に加えた変更の意図を把握する上で重要となります。
技術的詳細
このコミットにおける技術的な変更は、Go言語の公式仕様書 doc/go_spec.html
の内容をより正確かつ網羅的にすることに焦点を当てています。
-
SwitchStat
文法規則の追加: 以前の仕様では、ExprSwitchStat
(式スイッチ) とTypeSwitchStat
(型スイッチ) が個別に定義されていましたが、それらを包括する上位の概念であるSwitchStat
が明示的に定義されていませんでした。このコミットでは、以下の文法規則が追加されました。<pre class="grammar"> SwitchStat = ExprSwitchStat | TypeSwitchStat . </pre>
これは、
switch
ステートメントが、式スイッチと型スイッチのいずれかであることを明確に示しています。これにより、仕様の階層構造がより論理的になり、読者がswitch
ステートメントの全体像を把握しやすくなります。言語の文法を定義する上で、このような包括的な規則は、構文解析の観点からも重要です。 -
文法規則のインデント調整:
ExprSwitchStat
、ExprCaseClause
、ExprSwitchCase
、TypeSwitchStat
、TypeSwitchGuard
、TypeCaseClause
、TypeSwitchCase
といった既存の文法規則の<pre class="grammar">
ブロック内のインデントが調整されました。これは機能的な変更ではなく、ドキュメントの可読性を向上させるための整形です。仕様書は、その正確性だけでなく、読みやすさも重要であるため、このような細かな調整も品質向上に寄与します。 -
fallthrough
ステートメントの適用範囲の明確化: 最も重要な変更点の一つは、fallthrough
ステートメントの説明が修正されたことです。以前の記述では、fallthrough
が「switch
ステートメント」全般に適用されるかのように読める可能性がありました。しかし、Go言語の設計上、fallthrough
は式スイッチでのみ意味を持ち、型スイッチでは使用できません。このコミットでは、その点を明確にするために、説明文が以下のように変更されました。-
変更前:
A "fallthrough" statement transfers control to the first statement of the next case clause in a "switch" statement (§Switch statements). It may be used only as the final non-empty statement in a case or default clause in a "switch" statement.
(「fallthrough」ステートメントは、「switch」ステートメント(§Switchステートメント)内の次のcase節の最初のステートメントに制御を移します。これは、「switch」ステートメントのcaseまたはdefault節の最後の非空ステートメントとしてのみ使用できます。) -
変更後:
A "fallthrough" statement transfers control to the first statement of the next case clause in a expression "switch" statement (§Expression switches). It may be used only as the final non-empty statement in a case or default clause in an expression "switch" statement.
(「fallthrough」ステートメントは、式「switch」ステートメント(§Expressionスイッチ)内の次のcase節の最初のステートメントに制御を移します。これは、式「switch」ステートメントのcaseまたはdefault節の最後の非空ステートメントとしてのみ使用できます。)
この変更により、「
switch
ステートメント」という一般的な表現が「式switch
ステートメント」という具体的な表現に置き換えられました。これにより、fallthrough
の適用が式スイッチに限定されることが明確になり、読者の誤解を防ぎます。これは、言語のセマンティクスに関する重要な詳細であり、コンパイラの実装や、Goコードを書く開発者にとって正確な情報を提供するために不可欠です。 -
これらの変更は、Go言語の仕様が初期段階からいかに厳密に、そして詳細に定義されてきたかを示しています。
コアとなるコードの変更箇所
変更は doc/go_spec.html
ファイルに対して行われました。
--- a/doc/go_spec.html
+++ b/doc/go_spec.html
@@ -3133,6 +3133,11 @@ if x := f(); x < y {\n An expression or type specifier is compared to the "cases"\n inside the "switch" to determine which branch\n to execute.\n+\n+<pre class=\"grammar\">\n+SwitchStat = ExprSwitchStat | TypeSwitchStat .\n+</pre>\n+\n There are two forms: expression switches and type switches.\n In an expression switch, the cases contain expressions that are compared\n against the value of the switch expression.\n@@ -3159,10 +3164,9 @@ the expression <code>true</code>.\n </p>\n \n <pre class=\"grammar\">\n-SwitchStat = ExprSwitchStat | TypeSwitchStat .\n-ExprSwitchStat = "switch" [ [ SimpleStat ] ";" ] [ Expression ] "{" { ExprCaseClause } "}" .\n-ExprCaseClause = ExprSwitchCase ":" [ StatementList ] .\n-ExprSwitchCase = "case" ExpressionList | "default" .\n+ExprSwitchStat = "switch" [ [ SimpleStat ] ";" ] [ Expression ] "{" { ExprCaseClause } "}" .\n+ExprCaseClause = ExprSwitchCase ":" [ StatementList ] .\n+ExprSwitchCase = "case" ExpressionList | "default" .\n </pre>\n \n <p>\n@@ -3217,10 +3221,10 @@ in the type guard.\n </p>\n \n <pre class=\"grammar\">\n-TypeSwitchStat = "switch" [ [ SimpleStat ] ";" ] TypeSwitchGuard "{" { TypeCaseClause } "}" .\n-TypeSwitchGuard = identifier ":=" Expression "." "(" "type" ")" .\n-TypeCaseClause = TypeSwitchCase ":" [ StatementList ] .\n-TypeSwitchCase = "case" type | "default" .\n+TypeSwitchStat = "switch" [ [ SimpleStat ] ";" ] TypeSwitchGuard "{" { TypeCaseClause } "}" .\n+TypeCaseClause = TypeSwitchCase ":" [ StatementList ] .\n+TypeSwitchCase = "case" type | "default" .\n </pre>\n \n <p>\n@@ -3642,9 +3646,9 @@ the creation of <code>v</code>.\n \n <p>\n A "fallthrough" statement transfers control to the first statement of the\n-next case clause in a "switch" statement (§Switch statements). It may\n-be used only as the final non-empty statement in a case or default clause in a\n-"switch" statement.\n+next case clause in a expression "switch" statement (§Expression switches). It may\n+be used only as the final non-empty statement in a case or default clause in an\n+expression "switch" statement.\n </p>\n \n <pre class=\"grammar\">\n```
## コアとなるコードの解説
このコミットは、Go言語の仕様書 `doc/go_spec.html` 内の `switch` ステートメントに関する記述を修正しています。
1. **`SwitchStat` 文法規則の追加 (行 3136-3138)**:
```html
<pre class="grammar">
SwitchStat = ExprSwitchStat | TypeSwitchStat .
</pre>
```
この変更は、`switch` ステートメントが `ExprSwitchStat` (式スイッチ) または `TypeSwitchStat` (型スイッチ) のいずれかであることを明示的に定義しています。これにより、Go言語の `switch` ステートメントの全体的な文法構造がより明確になり、仕様の網羅性が向上しました。これは、言語の構文を形式的に記述する上で重要な追加です。
2. **既存の文法規則のインデント調整 (行 3162-3164, 3220-3222)**:
```diff
-SwitchStat = ExprSwitchStat | TypeSwitchStat .
-ExprSwitchStat = "switch" [ [ SimpleStat ] ";" ] [ Expression ] "{" { ExprCaseClause } "}" .
-ExprCaseClause = ExprSwitchCase ":" [ StatementList ] .
-ExprSwitchCase = "case" ExpressionList | "default" .
+ExprSwitchStat = "switch" [ [ SimpleStat ] ";" ] [ Expression ] "{" { ExprCaseClause } "}" .
+ExprCaseClause = ExprSwitchCase ":" [ StatementList ] .
+ExprSwitchCase = "case" ExpressionList | "default" .
```
```diff
-TypeSwitchStat = "switch" [ [ SimpleStat ] ";" ] TypeSwitchGuard "{" { TypeCaseClause } "}" .
-TypeSwitchGuard = identifier ":=" Expression "." "(" "type" ")" .
-TypeCaseClause = TypeSwitchCase ":" [ StatementList ] .
-TypeSwitchCase = "case" type | "default" .\n
+TypeSwitchStat = "switch" [ [ SimpleStat ] ";" ] TypeSwitchGuard "{" { TypeCaseClause } "}" .
+TypeCaseClause = TypeSwitchCase ":" [ StatementList ] .
+TypeSwitchCase = "case" type | "default" .
```
これらの変更は、`ExprSwitchStat`、`ExprCaseClause`、`ExprSwitchCase`、`TypeSwitchStat`、`TypeSwitchGuard`、`TypeCaseClause`、`TypeSwitchCase` の文法定義のインデントを調整したものです。これは、ドキュメントの視覚的な整合性と可読性を向上させるための純粋な整形変更であり、言語のセマンティクスには影響しません。ただし、`SwitchStat` の定義が新しい位置に移動したため、古い `SwitchStat` の行は削除されています。
3. **`fallthrough` ステートメントの説明の明確化 (行 3646-3648)**:
```diff
-next case clause in a "switch" statement (§Switch statements). It may
-be used only as the final non-empty statement in a case or default clause in a
-"switch" statement.
+next case clause in a expression "switch" statement (§Expression switches). It may
+be used only as the final non-empty statement in a case or default clause in an
+expression "switch" statement.
```
この変更は、`fallthrough` キーワードの適用範囲をより正確に記述するために行われました。以前の記述では、「`switch` ステートメント」全般に `fallthrough` が適用されるかのように読める可能性がありましたが、Go言語では `fallthrough` は**式スイッチ**でのみ有効です。この修正により、説明文が「`expression "switch" statement`」(式「switch」ステートメント)に具体化され、`fallthrough` が型スイッチでは使用できないことが明確になりました。これは、Go言語の制御フローのセマンティクスに関する重要な詳細であり、開発者が `fallthrough` を誤用するのを防ぐ上で非常に役立ちます。
これらの変更は全体として、Go言語の仕様書をより正確で、理解しやすく、曖昧さのないものにするための継続的な取り組みの一環です。
## 関連リンク
* Go言語の公式ドキュメント: [https://go.dev/doc/](https://go.dev/doc/)
* Go言語の仕様書: [https://go.dev/ref/spec](https://go.dev/ref/spec) (このコミットが修正したドキュメントの現在のバージョン)
## 参考にした情報源リンク
* Go言語の `switch` ステートメントに関する公式ドキュメント: [https://go.dev/ref/spec#Switch_statements](https://go.dev/ref/spec#Switch_statements)
* Go言語の `fallthrough` キーワードに関する公式ドキュメント: [https://go.dev/ref/spec#Fallthrough_statements](https://go.dev/ref/spec#Fallthrough_statements)
* Go言語の初期開発に関する情報 (Goの歴史): [https://go.dev/doc/history](https://go.dev/doc/history)