[インデックス 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
文とは異なり、より柔軟な構文を持ちます。
- 条件式のみ:
for condition {}
-condition
がtrue
である限りループを続けます。 - 初期化、条件、後処理:
for init; condition; post {}
- 伝統的なfor
ループ。 - 無限ループ:
for {}
- 条件式を省略すると無限ループになります。これはfor true {}
と等価です。
Go言語のswitch
文
Go言語のswitch
文もまた、柔軟な構文を持ちます。
- 式による
switch
:switch expression {}
-expression
の値に基づいてcase
を評価します。 - タグなし
switch
:switch {}
-switch
の後に式を省略すると、これはswitch true {}
と等価になります。この場合、各case
節はブール式である必要があります。最初にtrue
と評価されたcase
が実行されます。
Go言語におけるtrue
Go言語には、組み込みのブール型定数true
とfalse
が存在します。これらはキーワードではなく、事前宣言された識別子です。Go言語では、これらの事前宣言された識別子をローカルスコープで再定義することが可能です。
例:
package main
import "fmt"
func main() {
fmt.Println(true) // true
true := false // ローカルスコープでtrueを再定義
fmt.Println(true) // false
// この関数スコープ内では、trueはfalseを指す
// しかし、組み込みのtrue定数は依然として存在する
}
この再定義の可能性が、仕様書の記述の曖昧さを生んでいました。for
やswitch
で条件が省略された場合に、それが「ローカルで再定義された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 valuetrue
.」for
文: 「If the condition is absent, it is equivalent to the boolean valuetrue
.」
重要なのは、「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箇所が変更されています。
-
仕様書のバージョン日付の更新:
"Subtitle": "Version of Jan 14, 2014"
から"Subtitle": "Version of Feb 25, 2014"
へと変更されています。これは、仕様書の内容が更新されたことを示す標準的な手続きです。 -
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
定数が参照されることが保証されます。 -
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: https://go.dev/ref/spec
- Issue 7404: spec: clarify default "true" condition/tag in for/switch statements: https://github.com/golang/go/issues/7404
- Gerrit Code Review for this commit: https://golang.org/cl/68150046
参考にした情報源リンク
- Go Programming Language Specification (公式ドキュメント)
- GitHubのgolang/goリポジトリのコミット履歴
- Go言語のIssueトラッカー (Issue 7404)
- Gerrit Code Reviewシステム (CL 68150046)
- Go言語における
true
の再定義に関する一般的な知識