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

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

このコミットは、Go言語の仕様書(doc/go_spec.html)におけるfor文およびswitch文の条件式が省略された場合の挙動に関する記述を明確にするものです。具体的には、省略された条件が単なる式としてのtrueではなく、組み込み定数としてのtrueに相当することを明記しています。これは言語の動作変更ではなく、仕様の記述をより厳密にするための修正です。

コミット

commit ab26623182bb94e1b29668d86b5ee387991926fe
Author: Robert Griesemer <gri@golang.org>
Date:   Tue Feb 25 09:13:37 2014 -0800

    spec: clarify default "true" condition/tag in for/switch statements
    
    An absent condition/tag in for and switch statements is equivalent
    to the predeclared constant true; not simply the expression true
    (which might lead to a locally defined true).
    
    Not a language change.
    
    Fixes #7404.
    
    LGTM=iant, r
    R=r, iant, rsc, ken
    CC=golang-codereviews
    https://golang.org/cl/68150046

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

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

元コミット内容

このコミットの元のメッセージは以下の通りです。

spec: clarify default "true" condition/tag in for/switch statements

An absent condition/tag in for and switch statements is equivalent
to the predeclared constant true; not simply the expression true
(which might lead to a locally defined true).

Not a language change.

Fixes #7404.

変更の背景

Go言語のfor文やswitch文では、条件式やタグ(switch文の対象となる式)を省略することができます。例えば、for {}は無限ループを意味し、switch {}switch true {}と同じ意味になります。

このコミットが行われる前は、Goの仕様書において、これらの省略された条件が単に「trueに等しい」と記述されていました。しかし、Go言語ではtrueという識別子をユーザーがローカルで再定義することが可能です(例: true := false)。このような状況下で、仕様書が単に「trueに等しい」と記述していると、ユーザーが再定義したtrueが適用されるかのような誤解を招く可能性がありました。

このコミットは、このような曖昧さを解消し、省略された条件が常にGo言語に組み込まれた「事前宣言された定数true」に相当することを明確にするために行われました。これは言語の動作を変更するものではなく、あくまで仕様書の記述をより正確で誤解の余地のないものにするための修正です。

関連するIssue #7404は、この仕様の曖昧さについて議論されたものです。

前提知識の解説

Go言語のfor

Go言語のfor文は、C言語やJavaのfor文とは異なり、より柔軟な構文を持ちます。

  1. 条件式のみ: for condition {} - conditiontrueである限りループを続けます。
  2. 初期化、条件、後処理: for init; condition; post {} - 伝統的なforループ。
  3. 無限ループ: for {} - 条件式を省略すると無限ループになります。これはfor true {}と等価です。

Go言語のswitch

Go言語のswitch文もまた、柔軟な構文を持ちます。

  1. 式によるswitch: switch expression {} - expressionの値に基づいてcaseを評価します。
  2. タグなしswitch: switch {} - switchの後に式を省略すると、これはswitch true {}と等価になります。この場合、各case節はブール式である必要があります。最初にtrueと評価されたcaseが実行されます。

Go言語におけるtrue

Go言語には、組み込みのブール型定数truefalseが存在します。これらはキーワードではなく、事前宣言された識別子です。Go言語では、これらの事前宣言された識別子をローカルスコープで再定義することが可能です。

例:

package main

import "fmt"

func main() {
    fmt.Println(true) // true

    true := false // ローカルスコープでtrueを再定義
    fmt.Println(true) // false

    // この関数スコープ内では、trueはfalseを指す
    // しかし、組み込みのtrue定数は依然として存在する
}

この再定義の可能性が、仕様書の記述の曖昧さを生んでいました。forswitchで条件が省略された場合に、それが「ローカルで再定義されたtrue」を参照するのか、「組み込みの定数true」を参照するのかが不明確だったのです。

技術的詳細

このコミットの技術的な核心は、Go言語の仕様書(doc/go_spec.html)内の特定の箇所を修正し、trueという言葉の解釈を明確にすることです。

変更前は、switch文のセクションで「A missing switch expression is equivalent to the expression true.」と記述されていました。同様に、for文のセクションでは「If the condition is absent, it is equivalent to true.」と記述されていました。

このコミットでは、これらの記述を以下のように変更しています。

  • switch文: 「A missing switch expression is equivalent to the boolean value true.」
  • for文: 「If the condition is absent, it is equivalent to the boolean value true.」

重要なのは、「the expression true」から「the boolean value true」への変更です。 「the expression true」という表現は、Go言語の文脈では、ローカルスコープで再定義されたtrue識別子を参照する可能性を排除できませんでした。例えば、true := falseと書かれたコードブロック内でfor {}と書かれた場合、もし「the expression true」が適用されるなら、そのループはfor false {}と解釈され、実行されないという誤った解釈が生じる可能性がありました。

しかし、Go言語の設計意図としては、for {}switch {}は常に無限ループやswitch true {}(組み込みのtrue定数を使用)として振る舞うべきです。このため、仕様書は「the boolean value true」という表現に修正されました。これは、ローカルスコープでのtrueの再定義に関わらず、常に組み込みのブール定数trueを参照することを明確に示しています。

この変更は、Goコンパイラの動作に影響を与えるものではなく、既存のGoプログラムの挙動を変えるものでもありません。これは、Go言語の仕様が、言語の実際の動作と完全に一致するように、より厳密かつ正確に記述されることを保証するためのドキュメント修正です。

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

変更はdoc/go_spec.htmlファイルのみです。

--- a/doc/go_spec.html
+++ b/doc/go_spec.html
@@ -1,6 +1,6 @@
 <!--{
  	"Title": "The Go Programming Language Specification",
-	"Subtitle": "Version of Jan 14, 2014",
+	"Subtitle": "Version of Feb 25, 2014",
  	"Path": "/ref/spec"
 }-->
 
@@ -4459,8 +4459,8 @@ If no case matches and there is a "default" case,
 its statements are executed.
 There can be at most one default case and it may appear anywhere in the
 "switch" statement.
-A missing switch expression is equivalent to
-the expression <code>true</code>.
+A missing switch expression is equivalent to the boolean value
+<code>true</code>.
 </p>
 
 <pre class="ebnf">
@@ -4625,7 +4625,8 @@ Condition = Expression .
 In its simplest form, a "for" statement specifies the repeated execution of
 a block as long as a boolean condition evaluates to true.
 The condition is evaluated before each iteration.
-If the condition is absent, it is equivalent to <code>true</code>.
+If the condition is absent, it is equivalent to the boolean value
+<code>true</code>.\n
 </p>
 
 <pre>
@@ -4662,7 +4663,8 @@ only if the block was executed).\n Any element of the ForClause may be empty but the
 <a href=\"#Semicolons\">semicolons</a> are
 required unless there is only a condition.
-If the condition is absent, it is equivalent to <code>true</code>.
+If the condition is absent, it is equivalent to the boolean value
+<code>true</code>.
 </p>
 
 <pre>

コアとなるコードの解説

上記の差分が示すように、以下の3箇所が変更されています。

  1. 仕様書のバージョン日付の更新: "Subtitle": "Version of Jan 14, 2014" から "Subtitle": "Version of Feb 25, 2014" へと変更されています。これは、仕様書の内容が更新されたことを示す標準的な手続きです。

  2. switch文の条件省略に関する記述の修正: - A missing switch expression is equivalent to the expression <code>true</code>. + A missing switch expression is equivalent to the boolean value <code>true</code>. switch文で式が省略された場合、それが「式としてのtrue」ではなく、「ブール値としてのtrue」に等しいことを明確にしています。これにより、ローカルでtrueが再定義されていても、常に組み込みのtrue定数が参照されることが保証されます。

  3. for文の条件省略に関する記述の修正(2箇所): - If the condition is absent, it is equivalent to <code>true</code>. + If the condition is absent, it is equivalent to the boolean value <code>true</code>. for文で条件が省略された場合も同様に、「ブール値としてのtrue」に等しいことが明記されました。これにより、for {}が常に無限ループとして機能することが、仕様上も明確になります。

これらの変更は、Go言語の仕様書が、言語の実際のセマンティクスをより正確に反映し、開発者が誤解する可能性を減らすことを目的としています。

関連リンク

参考にした情報源リンク

  • Go Programming Language Specification (公式ドキュメント)
  • GitHubのgolang/goリポジトリのコミット履歴
  • Go言語のIssueトラッカー (Issue 7404)
  • Gerrit Code Reviewシステム (CL 68150046)
  • Go言語におけるtrueの再定義に関する一般的な知識