[インデックス 15678] ファイルの概要
このコミットは、Go言語の仕様書 (doc/go_spec.html
) における比較演算子の結果の型に関する記述を修正するものです。具体的には、比較演算の結果が常に「型なしの真偽値 (untyped bool)」であることを明確にする変更が加えられました。これにより、Go言語の型システムにおける比較結果の振る舞いがより正確に定義され、開発者にとっての理解が深まります。
コミット
commit c729ed631f1de47c7fb1fb2413b6f69be6d0f3bb
Author: Robert Griesemer <gri@golang.org>
Date: Mon Mar 11 09:16:29 2013 -0700
spec: result type of a comparison is always untyped bool
For details see the cited issue.
Fixes #4793.
R=rsc, r, iant, ken
CC=golang-dev
https://golang.org/cl/7524044
---
doc/go_spec.html | 21 +++++++++------------
1 file changed, 9 insertions(+), 12 deletions(-)
diff --git a/doc/go_spec.html b/doc/go_spec.html
index 5268a5b16d..992c4718a5 100644
--- a/doc/go_spec.html
+++ b/doc/go_spec.html
@@ -1,6 +1,6 @@
<!--{
"Title": "The Go Programming Language Specification",
-" "Subtitle": "Version of March 7, 2013",
+" "Subtitle": "Version of March 11, 2013",
"Path": "/ref/spec"
}-->
@@ -3108,7 +3108,7 @@ not occur. For instance, it may not assume that <code>x < x + 1</code> is alw
<h3 id="Comparison_operators">Comparison operators</h3>
<p>
-Comparison operators compare two operands and yield a boolean value.
+Comparison operators compare two operands and yield an untyped boolean value.
</p>
<pre class="grammar">
@@ -3216,20 +3216,17 @@ Comparison of pointer, channel, and interface values to <code>nil</code>
is also allowed and follows from the general rules above.
</p>
-<p>
-The result of a comparison can be assigned to any boolean type.
-If the context does not demand a specific boolean type,
-the result has type <code>bool</code>.
-</p>
-\n <pre>
-type MyBool bool
+const c = 3 < 4 // c is the untyped bool constant true
\n+type MyBool bool
var x, y int
var (
-\tb1 MyBool = x == y // result of comparison has type MyBool
-\tb2 bool = x == y // result of comparison has type bool
-\tb3 = x == y // result of comparison has type bool
+\t// The result of a comparison is an untyped bool.
+\t// The usual assignment rules apply.
+\tb3 = x == y // b3 has type bool
+\tb4 bool = x == y // b4 has type bool
+\tb5 MyBool = x == y // b5 has type MyBool
)\n </pre>
\n
GitHub上でのコミットページへのリンク
https://github.com/golang/go/commit/c729ed631f1de47c7fb1fb2413b6f69be6d0f3bb
元コミット内容
spec: result type of a comparison is always untyped bool
For details see the cited issue.
Fixes #4793.
R=rsc, r, iant, ken
CC=golang-dev
https://golang.org/cl/7524044
変更の背景
この変更の背景には、Go言語の型システムにおける比較演算子の結果の振る舞いをより厳密に定義し、曖昧さを排除するという目的があります。Go言語には「型なし定数 (untyped constants)」という概念があり、これはリテラル値(例: 10
, 3.14
, "hello"
, true
)が特定の型を持たずに存在することを指します。これらの型なし定数は、使用される文脈によって適切な型に「型付け」されます。
比較演算子(例: ==
, !=
, <
, <=
, >
, >=
)の結果もまた、このような型なしの性質を持つべきであるという認識がありました。以前の仕様では、比較の結果が「ブール値 (boolean value)」を生成するとだけ記述されており、その型が具体的にどのように扱われるかについての詳細が不足していました。特に、ユーザー定義のブール型 (type MyBool bool
) への代入や、型推論の挙動に関して、より明確なルールが必要とされていました。
このコミットは、比較演算の結果が常に「型なしの真偽値 (untyped bool)」であると明記することで、この曖昧さを解消し、Go言語の型推論と代入規則との整合性を高めることを目的としています。これにより、コンパイラの実装がより一貫性を持つようになり、開発者は比較結果の型がどのように決定されるかを正確に理解できるようになります。
コミットメッセージにある Fixes #4793
は、この変更が特定の課題(issue)を解決するものであることを示唆していますが、Go言語の公式リポジトリではこの番号のissueは直接見つかりませんでした。しかし、これはGo言語の仕様に関する議論や、コンパイラの挙動に関する問題提起が背景にあった可能性が高いです。
前提知識の解説
このコミットを理解するためには、以下のGo言語の概念を理解しておく必要があります。
1. Go言語の型システム
Go言語は静的型付け言語であり、変数は宣言時に型を持ちます。型は、その変数が保持できる値の種類と、その値に対して実行できる操作を決定します。
2. 比較演算子 (Comparison Operators)
Go言語における比較演算子は、2つのオペランドを比較し、その結果として真偽値(true
または false
)を返します。主な比較演算子には以下があります。
==
(等しい)!=
(等しくない)<
(より小さい)<=
(より小さいか等しい)>
(より大きい)>=
(より大きいか等しい)
これらの演算子は、数値、文字列、ブール値、ポインタ、チャネル、インターフェースなど、様々な型の値に適用できます。
3. 型なし定数 (Untyped Constants)
Go言語には「型なし定数」という特別な概念があります。これは、数値リテラル(例: 10
, 3.14
)、文字列リテラル(例: "hello"
)、ブールリテラル(例: true
, false
)などが、初期段階では特定のGoの型を持たないことを意味します。
型なし定数は、その値が使用される文脈(代入、演算、関数呼び出しなど)に基づいて、適切なGoの型に「型付け (typed)」されます。例えば、const x = 10
の 10
は型なしの整数定数であり、var i int = x
のように int
型の変数に代入されると int
型に型付けされます。この柔軟性により、Go言語では数値の精度を失うことなく、異なる数値型間での演算や代入をより自然に行うことができます。
4. 型推論 (Type Inference)
Go言語は型推論をサポートしています。変数を宣言する際に明示的に型を指定しない場合、コンパイラは初期値から変数の型を推論します。
例:
var i = 10 // i は int 型と推論される
var s = "hello" // s は string 型と推論される
5. ユーザー定義型 (User-defined Types)
Go言語では、既存の型を基にして新しい型を定義することができます。
例:
type MyInt int
type MyBool bool
MyInt
は int
とは異なる型であり、MyBool
は bool
とは異なる型です。たとえ基底型が同じであっても、異なる型として扱われます。
技術的詳細
このコミットの技術的な核心は、「比較演算の結果が常に型なしの真偽値 (untyped bool) である」という仕様の明確化にあります。
以前の仕様では、比較演算子が「ブール値 (boolean value)」を生成するとだけ述べられていました。この記述だけでは、そのブール値が bool
型なのか、それとも型なしのブール定数なのかが不明確でした。
この変更により、以下のような挙動が明確になります。
-
型なしの真偽値としての生成:
x == y
のような比較演算の結果は、まずtrue
またはfalse
という「型なしの真偽値定数」として生成されます。これは、数値リテラル10
が型なしの整数定数として扱われるのと同様です。 -
文脈に応じた型付け: この型なしの真偽値は、それが使用される文脈(代入、型変換、関数引数など)に基づいて、具体的なGoのブール型に型付けされます。
-
明示的な型への代入:
type MyBool bool var b5 MyBool = x == y // x == y の結果は MyBool 型に型付けされる
この場合、
x == y
の結果である型なしの真偽値は、代入先のMyBool
型に変換されます。これは、var i int = 10
のように型なしの整数定数10
がint
型に変換されるのと同様のメカニズムです。 -
型推論による代入:
var b3 = x == y // b3 は bool 型と推論される
型が明示されていない場合、Goの型推論規則に従い、型なしの真偽値はデフォルトのブール型である
bool
型に推論されます。 -
bool
型への明示的な代入:var b4 bool = x == y // b4 は bool 型
この場合も、型なしの真偽値が
bool
型に型付けされます。
-
この変更は、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 March 7, 2013",
+" "Subtitle": "Version of March 11, 2013",
"Path": "/ref/spec"
}-->
@@ -3108,7 +3108,7 @@ not occur. For instance, it may not assume that <code>x < x + 1</code> is alw
<h3 id="Comparison_operators">Comparison operators</h3>
<p>
-Comparison operators compare two operands and yield a boolean value.
+Comparison operators compare two operands and yield an untyped boolean value.
</p>
<pre class="grammar">
@@ -3216,20 +3216,17 @@ Comparison of pointer, channel, and interface values to <code>nil</code>
is also allowed and follows from the general rules above.\n</p>
-<p>
-The result of a comparison can be assigned to any boolean type.
-If the context does not demand a specific boolean type,
-the result has type <code>bool</code>.
-</p>
-\n <pre>
-type MyBool bool
+const c = 3 < 4 // c is the untyped bool constant true
\n+type MyBool bool
var x, y int
var (
-\tb1 MyBool = x == y // result of comparison has type MyBool
-\tb2 bool = x == y // result of comparison has type bool
-\tb3 = x == y // result of comparison has type bool
+\t// The result of a comparison is an untyped bool.
+\t// The usual assignment rules apply.
+\tb3 = x == y // b3 has type bool
+\tb4 bool = x == y // b4 has type bool
+\tb5 MyBool = x == y // b5 has type MyBool
)\n </pre>
\n
コアとなるコードの解説
このコミットは、Go言語の公式仕様書である doc/go_spec.html
の記述を修正しています。
-
仕様書のバージョン日付の更新:
-" "Subtitle": "Version of March 7, 2013", +" "Subtitle": "Version of March 11, 2013",
これは単に仕様書のバージョン日付を更新したものです。
-
比較演算子の結果の型の明確化:
-<p> -Comparison operators compare two operands and yield a boolean value. +<p> +Comparison operators compare two operands and yield an untyped boolean value. </p>
ここが最も重要な変更点です。以前は「ブール値 (boolean value)」を生成するとだけ書かれていた箇所が、「型なしの真偽値 (untyped boolean value)」を生成すると明確に修正されました。これにより、比較結果が型なし定数として扱われることが明示されます。
-
型付けに関する記述の削除と新しい例の追加:
-<p> -The result of a comparison can be assigned to any boolean type. -If the context does not demand a specific boolean type, -the result has type <code>bool</code>. -</p> -\n <pre> -type MyBool bool +const c = 3 < 4 // c is the untyped bool constant true \n+type MyBool bool var x, y int var ( -\tb1 MyBool = x == y // result of comparison has type MyBool -\tb2 bool = x == y // result of comparison has type bool -\tb3 = x == y // result of comparison has type bool +\t// The result of a comparison is an untyped bool. +\t// The usual assignment rules apply. +\tb3 = x == y // b3 has type bool +\tb4 bool = x == y // b4 has type bool +\tb5 MyBool = x == y // b5 has type MyBool )\n </pre>
- 以前の「比較の結果は任意のブール型に代入でき、文脈が特定のブール型を要求しない場合は
bool
型になる」という記述が削除されました。これは、新しい「型なしの真偽値」という概念が導入されたため、この記述が不要になったためです。型なし定数の規則が適用されることで、この挙動は自然に導かれます。 - 新しいコード例が追加されました。
const c = 3 < 4
の例は、比較結果が型なしのブール定数として扱われることを示しています。c
は型なしのブール定数true
となります。var b3 = x == y
の例では、型が明示されていないため、x == y
の結果である型なしの真偽値がデフォルトのbool
型に推論され、b3
はbool
型になります。var b4 bool = x == y
の例では、明示的にbool
型に代入されているため、b4
はbool
型になります。var b5 MyBool = x == y
の例では、ユーザー定義型MyBool
に代入されているため、x == y
の結果である型なしの真偽値がMyBool
型に変換され、b5
はMyBool
型になります。
- 以前の「比較の結果は任意のブール型に代入でき、文脈が特定のブール型を要求しない場合は
これらの変更は、Go言語の仕様をより正確かつ一貫性のあるものにし、特に型なし定数の概念が比較演算の結果にも適用されることを明確にしています。これにより、Go言語の型システムがより堅牢になり、開発者がコードの挙動を予測しやすくなります。
関連リンク
- GitHubコミットページ: https://github.com/golang/go/commit/c729ed631f1de47c7fb1fb2413b6f69be6d0f3bb
- Go言語仕様書 (Go Programming Language Specification): https://golang.org/ref/spec
参考にした情報源リンク
- Go言語仕様書 (Go Programming Language Specification)
- Go言語の型システムに関する一般的な知識
- Go言語における型なし定数に関する情報