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

[インデックス 177] ファイルの概要

このコミットは、Go言語の初期の仕様書である doc/go_lang.txt における if および switch ステートメントの文法定義を修正し、より正確かつ柔軟な記述を可能にするものです。特に、これらの制御構造におけるオプション要素(初期化ステートメントや条件式)の扱いが明確化されています。

コミット

commit daebf91d2c0e719a7b59ba1c26ccc8def83e39bc
Author: Rob Pike <r@golang.org>
Date:   Mon Jun 16 12:02:27 2008 -0700

    fix up grammar for optional elements in if and switch conditions
    
    SVN=122915

GitHub上でのコミットページへのリンク

https://github.com/golang/go/commit/daebf91d2c0e719a7b59ba1c26ccc8def83e39bc

元コミット内容

fix up grammar for optional elements in if and switch conditions

このコミットメッセージは、if および switch ステートメントにおけるオプション要素(条件式や初期化ステートメント)の文法定義を修正したことを簡潔に示しています。SVN=122915 は、この変更がGo言語のリポジトリがGitに移行する前のSubversionリビジョン122915に由来することを示しています。

変更の背景

Go言語は設計段階から簡潔さと実用性を重視しており、その文法も進化を続けていました。このコミットが行われた2008年6月は、Go言語がまだ一般に公開される前の初期開発段階にあたります。この時期には、言語仕様の細部が頻繁に議論され、調整されていました。

ifswitch ステートメントにおける初期化ステートメント(SimpleStat)や条件式の扱いは、コードの記述性や可読性に大きく影響します。初期の文法定義には、これらのオプション要素の記述に関して曖昧さや、意図しない制約があった可能性があります。

具体的には、以下の点が背景にあると考えられます。

  1. 文法定義の明確化: doc/go_lang.txt はGo言語の公式な仕様書であり、その文法定義は厳密である必要があります。初期の定義が、実際の言語の挙動や設計思想と完全に一致していなかった、あるいは誤解を招く可能性があったため、より正確な記述が求められました。
  2. if ステートメントにおける条件の省略: Go言語の if ステートメントでは、条件式を省略した場合に true とみなされるという特徴があります。しかし、初期化ステートメントが伴う場合にこの省略が許されるかどうかが不明確だった可能性があります。このコミットは、初期化ステートメントがあっても条件を省略できる(そして true とみなされる)という挙動を明確にするために行われました。
  3. switch ステートメントにおける式の省略: Go言語の switch ステートメントには、式を伴わない「裸の switch」(bare switch)という形式があります。これは、case 句がブール式を評価する if-else if の連鎖のような振る舞いをします。初期の文法定義では、この「裸の switch」の形式が十分に表現されていなかったか、あるいはそのオプション性が明確でなかった可能性があります。

これらの背景から、Go言語の設計者たちは、より一貫性があり、かつ柔軟な制御フローの記述を可能にするために、文法定義の修正を行ったと考えられます。

前提知識の解説

このコミットの変更内容を理解するためには、Go言語における以下の基本的な文法と概念を理解しておく必要があります。

1. Go言語の if ステートメント

Go言語の if ステートメントは、他の多くのC系言語と似ていますが、いくつかの特徴があります。

  • 括弧の省略: 条件式を括弧で囲む必要はありません。
  • 波括弧の必須: then ブロックは必ず波括弧 {} で囲む必要があります。
  • 初期化ステートメント: if ステートメントの条件式の前に、セミコロン ; で区切って短い初期化ステートメント(SimpleStat)を記述できます。ここで宣言された変数のスコープは、if ステートメント全体(else ブロックを含む)に限定されます。 例: if x := f(); x < y { ... }
  • 条件の省略: 条件式を省略した場合、その条件は true とみなされます。これは for ループの条件省略と同様の挙動です。 例: if { ... } は常に実行されます。

2. Go言語の switch ステートメント

Go言語の switch ステートメントも特徴的です。

  • 括弧の省略: switch 式を括弧で囲む必要はありません。
  • break の不要: 各 case 句の最後に break ステートメントを明示的に記述する必要はありません。Goでは、case がマッチするとそのブロックが実行され、自動的に switch ステートメントを抜けます。
  • fallthrough: 意図的に次の case 句に処理を継続させたい場合は、fallthrough キーワードを使用します。
  • 初期化ステートメント: if と同様に、switch 式の前に初期化ステートメントを記述できます。
  • 式の省略(Bare Switch): switch キーワードの後に式を記述しない「裸の switch」が可能です。この場合、各 case 句はブール式を評価し、最初に true となった case のブロックが実行されます。これは if-else if-else の連鎖をより簡潔に記述するのに役立ちます。 例:
    switch {
    case x < 0:
        // ...
    case x == 0:
        // ...
    default:
        // ...
    }
    
  • 型スイッチ: switch ステートメントは、インターフェース変数の動的な型をチェックするためにも使用できます。

3. 文法定義の表記

doc/go_lang.txt のような言語仕様書では、文法規則を記述するためにバッカス・ナウア記法(BNF)に似た形式が用いられます。

  • = : 定義
  • | : または (選択肢)
  • [ ... ] : オプション(0回または1回出現)
  • { ... } : 0回以上の繰り返し
  • "..." : リテラル(キーワードなど)
  • Name : 非終端記号(別の文法規則で定義される要素)

この表記法を理解することで、コミットで変更された文法規則の意味を正確に読み解くことができます。

技術的詳細

このコミットは、doc/go_lang.txt 内の IfStat (If statements) と SwitchStat (Switch statements) の文法定義を修正しています。

IfStat の変更点

1. 文法規則の変更

変更前: IfStat = "if" [ [ SimpleStat ";" ] Expression ] Block [ "else" Statement ] .

変更後: IfStat = "if" [ [ Simplestat ] ";" ] [ Condition ] Block [ "else" Statement ] .

この変更には以下の意図があります。

  • Expression から Condition への変更: Expression は一般的な式を指しますが、Condition はより具体的にブール値を評価する式を指します。これは、if ステートメントの文脈において、その位置に期待されるものが「条件」であることを明確にするためのセマンティックな変更です。Go言語では、if の条件は常にブール値でなければなりません。
  • [ SimpleStat ";" ] の表記の明確化: 変更前は [ [ SimpleStat ";" ] Expression ] のように、SimpleStat とセミコロンがセットでオプションであることを示していました。変更後は [ [ Simplestat ] ";" ] となり、Simplestat 自体がオプションであり、もし存在すればセミコロンが続く、という構造をより明確に表現しています。これは、SimpleStat が存在しない場合でもセミコロンが続く可能性を示唆するものではなく、SimpleStat があればセミコロンが必須であることを示しています。

2. 説明文の変更

変更前: The condition may be omitted in which If a variable is declared, the condition cannot be omitted.

変更後: The condition may be omitted, in which the variable is initialized once before the statement is entered.

この説明文の変更は非常に重要です。

  • 「The condition may be omitted in which」から「The condition may be omitted, in which」: これは単なる句読点の修正であり、文法的な意味合いの変更はありませんが、文章の可読性を向上させています。
  • 「If a variable is declared, the condition cannot be omitted.」の削除: この文の削除は、Go言語の if ステートメントの挙動における重要な変更を示唆しています。変更前は、「if ステートメントで変数を宣言した場合(例: if x := f(); ...)、条件式を省略することはできない」とされていました。しかし、この文が削除されたことにより、変数を宣言した場合でも条件式を省略できるようになったことを意味します。 Go言語の if ステートメントでは、条件式が省略された場合、その条件は true とみなされます。したがって、この変更により、if x := f(); { ... } のような形式が有効になり、f() の結果を x に代入しつつ、常にブロックを実行するという記述が可能になりました。これは、for ループの for { ... } (無限ループ) と同様の「条件省略時は true」という一貫した設計思想を if ステートメントにも適用したものです。

SwitchStat の変更点

1. 文法規則の変更

変更前: SwitchStat = "switch" [ [ SimpleStat ";" ] Expression ] "{" { CaseClause } "}" .

変更後: SwitchStat = "switch" [ [ Simplestat ] ";" ] [ Expression ] "{" { CaseClause } "}" .

この変更も IfStat と同様に、[ SimpleStat ";" ] の表記が [ Simplestat ] ";" ] に修正され、SimpleStat のオプション性がより明確に表現されています。

さらに重要なのは、Expression[ Expression ] となり、switch ステートメントの式がオプションになったことです。

  • Expression から [ Expression ] への変更: これにより、switch キーワードの後に式を記述しない「裸の switch」(bare switch)が文法的に正式に認められたことを意味します。裸の switch では、各 case 句がブール式を評価し、最初に true となった case のブロックが実行されます。これは、複数の条件を if-else if の連鎖で記述するよりも、構造的に整理されたコードを書くことを可能にします。

まとめ

このコミットは、Go言語の if および switch ステートメントの文法定義を、より正確で柔軟なものに修正しました。

  • if ステートメントでは、初期化ステートメントが存在する場合でも条件式を省略できる(そして true とみなされる)ようになりました。
  • switch ステートメントでは、式を省略した「裸の switch」が正式に文法として認められました。

これらの変更は、Go言語の制御フロー構造の設計における一貫性と表現力を向上させるものであり、言語の成熟に向けた重要な一歩と言えます。

コアとなるコードの変更箇所

変更は doc/go_lang.txt ファイルのみです。

--- a/doc/go_lang.txt
+++ b/doc/go_lang.txt
@@ -1582,10 +1582,10 @@ If statements
  
  If statements have the traditional form except that the
  condition need not be parenthesized and the "then" statement
-must be in brace brackets. The condition may be omitted in which
+must be in brace brackets. The condition may be omitted, in which
 case it is assumed to have the value "true".
  
-  IfStat = "if" [ [ SimpleStat ";" ] Expression ] Block [ "else" Statement ] .
+  IfStat = "if" [ [ Simplestat ] ";" ] [ Condition ] Block [ "else" Statement ] .
  
   if x > 0 {\n     return true;\n
 @@ -1593,8 +1593,7 @@ case it is assumed to have the value "true".
  
  An "if" statement may include the declaration of a single temporary variable.\n  The scope of the declared variable extends to the end of the if statement, and\n-the variable is initialized once before the statement is entered. If a variable\n-is declared, the condition cannot be omitted.\n+the variable is initialized once before the statement is entered.\n \n   if x := f(); x < y {\n     return x;\n@@ -1610,7 +1609,7 @@ Switch statements
  
  Switches provide multi-way execution.\n  
-  SwitchStat = "switch" [ [ SimpleStat ";" ] Expression ] "{" { CaseClause } "}" .
+  SwitchStat = "switch" [ [ Simplestat ] ";" ] [ Expression ] "{" { CaseClause } "}" .
   CaseClause = CaseList StatementList [ ";" ] [ "fallthrough" [ ";" ] ] .
   CaseList = Case { Case } .
   Case = ( "case" ExpressionList | "default" ) ":" .

コアとなるコードの解説

このコミットは、Go言語の文法定義を記述したドキュメントファイル doc/go_lang.txt のみを変更しています。実際のコンパイラやランタイムのコードを変更するものではありませんが、言語の挙動に関する公式な記述を修正することで、Go言語の仕様を明確にしています。

IfStat の変更

  1. IfStat = "if" [ [ SimpleStat ] ";" ] [ Condition ] Block [ "else" Statement ] .
    • [ SimpleStat ";" ] から [ Simplestat ] ";" ] への変更は、SimpleStat(初期化ステートメント)がオプションであり、もし存在すればセミコロンが続く、という文法構造をより正確に表現しています。
    • Expression から Condition への変更は、if ステートメントのこの位置にはブール値を評価する「条件」が来ることが期待されるという、セマンティックな明確化です。
  2. If a variable is declared, the condition cannot be omitted. の削除
    • この行の削除が、if ステートメントの挙動における最も重要な変更点です。これにより、if ステートメントで変数を宣言した場合(例: if x := f(); ...)でも、条件式を省略できる(そして true とみなされる)ようになりました。
    • 例: if x := f(); { fmt.Println(x) } のようなコードが有効になります。これは f() を実行して x に代入し、常に fmt.Println(x) を実行するという意味になります。

SwitchStat の変更

  1. SwitchStat = "switch" [ [ Simplestat ] ";" ] [ Expression ] "{" { CaseClause } "}" .
    • [ SimpleStat ";" ] から [ Simplestat ] ";" ] への変更は IfStat と同様です。
    • Expression から [ Expression ] への変更は、switch ステートメントの式がオプションになったことを意味します。これにより、switch キーワードの後に式を記述しない「裸の switch」(bare switch)が文法的に正式に認められました。
    • 例: switch { case x > 0: ... } のようなコードが有効になります。これは、case 句がブール式を評価する if-else if のような振る舞いをします。

これらの変更は、Go言語の初期開発段階における言語仕様の洗練と、より一貫性のある、かつ表現力の高い制御フロー構造の提供を目指したものです。ドキュメントの修正ではありますが、これはGo言語の文法がどのように進化していったかを示す重要な記録です。

関連リンク

参考にした情報源リンク