[インデックス 12125] ファイルの概要
このコミットは、Go言語の仕様書(doc/go_spec.html
)に対する変更であり、主に比較演算子の結果の型に関する挙動を明確にし、foo_bar
形式の変数名をfooBar
形式に修正しています。
コミット
commit 9c08d6508442a7491aeb615c52d69d38b1c477c6
Author: Russ Cox <rsc@golang.org>
Date: Tue Feb 21 22:04:30 2012 -0500
spec: make all comparison results untyped bool
Or, depending on your point of view, make the
comparisons satisfy any surrounding boolean type.
Also, fix a few foo_bar -> fooBar in code fragments.
Fixes #2561.
R=golang-dev, r, bradfitz, gri, iant, kevlar
CC=golang-dev
https://golang.org/cl/5671096
GitHub上でのコミットページへのリンク
https://github.com/golang/go/commit/9c08d6508442a7491aeb615c52d69d38b1c477c6
元コミット内容
Go言語の仕様書において、比較演算子の結果が「型なしのbool(untyped bool)」となるように変更するか、あるいは比較結果が周囲のboolean型に適合するように変更する。また、コードフラグメント内のfoo_bar
形式の変数名をfooBar
形式に修正する。この変更はIssue #2561を修正するものである。
変更の背景
このコミットは、Go言語のIssue #2561「x == y
should be an untyped boolean constant」を修正するために行われました。このIssueは、Go言語における比較演算子(例: ==
, <
, >=
など)の結果の型に関する曖昧さを指摘していました。
Go言語では、定数には「型なし(untyped)」の概念があります。これは、リテラル(例: 1
, 3.14
, "hello"
)が特定の型を持たず、文脈に応じて適切な型に変換されるというものです。しかし、比較演算の結果がどのような型を持つべきか、特にそれが定数式である場合に、仕様が明確ではありませんでした。
具体的には、x == y
のような比較式の結果が、常にbool
型になるのか、それとも型なしのboolean定数として扱われ、代入先の型に応じて型付けされるべきなのか、という点が議論の対象でした。この曖昧さは、Goプログラムの型推論や型チェックの挙動に影響を与え、開発者にとって混乱の原因となる可能性がありました。
このコミットの目的は、比較演算の結果が常に型なしのboolean定数として扱われるように仕様を明確化し、Go言語の型システムの一貫性と予測可能性を向上させることにありました。これにより、比較結果をカスタムのboolean型(例: type MyBool bool
)の変数に直接代入できるようになり、より柔軟な型付けが可能になります。
また、Go言語のコーディング規約では、変数名や関数名にキャメルケース(fooBar
)を使用することが推奨されています。コミットメッセージにある「fix a few foo_bar -> fooBar in code fragments」は、仕様書内のコード例がこの規約に従っていない箇所を修正し、Go言語のベストプラクティスを反映させるための変更です。
前提知識の解説
Go言語の型システムと「型なし(Untyped)」の概念
Go言語は静的型付け言語であり、すべての変数と式は特定の型を持ちます。しかし、Goには「型なし(untyped)」という特別な概念が存在します。これは主に数値、真偽値、文字列のリテラル定数に適用されます。
- 型なし定数:
10
,3.14
,true
,"hello"
のようなリテラルは、それ自体では特定のGoの型(例:int
,float64
,string
,bool
)を持ちません。これらは「型なし整数定数」「型なし浮動小数点定数」「型なし真偽値定数」「型なし文字列定数」と呼ばれます。 - 型付け: 型なし定数は、変数への代入や関数の引数として使用される際に、その文脈(代入先の変数の型や関数の引数の型)に基づいて型付けされます。例えば、
var i int = 10
の場合、型なし整数定数10
はint
型に型付けされます。 - 柔軟性: この型なしの概念により、Goは数値リテラルを異なる数値型(
int
,int32
,float64
など)に柔軟に適合させることができます。
Go言語における比較演算子
Go言語の比較演算子(==
, !=
, <
, <=
, >
, >=
)は、2つのオペランドを比較し、その結果として真偽値(true
またはfalse
)を返します。
このコミット以前の仕様では、比較演算の結果がどのような型を持つのか、特にそれが定数式の場合に、明確な記述が不足していました。この曖昧さが、型なしの概念と組み合わさることで、開発者が期待する挙動と実際の挙動の間に乖離が生じる可能性がありました。
このコミットの変更は、比較演算の結果が常に「型なしのbool定数」として扱われるようにすることで、この曖昧さを解消し、型なし定数の柔軟性を比較結果にも適用できるようにすることを目的としています。これにより、比較結果を任意のboolean型(組み込みのbool
型だけでなく、ユーザー定義のtype MyBool bool
のような型も含む)に代入できるようになります。
キャメルケース(CamelCase)
Go言語の公式スタイルガイドでは、変数名、関数名、メソッド名などにキャメルケースを使用することが推奨されています。キャメルケースには、先頭の文字を小文字にする「lowerCamelCase」(例: myVariable
, calculateSum
)と、先頭の文字を大文字にする「UpperCamelCase」(例: MyStruct
, ExportedFunction
)があります。Goでは、エクスポートされる(パッケージ外から参照可能な)識別子はUpperCamelCase、エクスポートされない(パッケージ内でのみ参照可能な)識別子はlowerCamelCaseを使用します。
このコミットでは、仕様書内のコード例でreply_chan
やchan_ptr
のようにアンダースコアで区切られたスネークケース(snake_case)が使用されていた箇所を、Goの慣習に従いreplyChan
やchanPtr
のようなキャメルケースに修正しています。これは、コードの可読性と一貫性を向上させるための変更です。
技術的詳細
このコミットの主要な技術的変更点は、Go言語の仕様書において、比較演算子の結果の型に関する記述を明確化したことです。
変更前は、比較演算子の結果が単に「bool
型」であると記述されていました。しかし、このコミットにより、「比較演算子は2つのオペランドを比較し、boolean値を生成する」という記述に変わり、さらに以下の重要な文言が追加されました。
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
bool
.
これは、比較演算の結果が「型なしのboolean定数」として扱われることを意味します。この「型なし」の性質により、比較結果は、代入先の変数の型がbool
型であろうと、ユーザー定義のtype MyBool bool
のようなカスタムのboolean型であろうと、その型に適合するように型付けされます。
例として、仕様書に追加された以下のコードフラグメントがこの挙動を示しています。
type MyBool bool
var x, y int
var (
b1 MyBool = x == y // result of comparison has type MyBool
b2 bool = x == y // result of comparison has type bool
b3 = x == y // result of comparison has type bool
)
b1 MyBool = x == y
:x == y
の結果は型なしのboolean定数として扱われ、MyBool
型に型付けされてb1
に代入されます。b2 bool = x == y
:x == y
の結果は型なしのboolean定数として扱われ、bool
型に型付けされてb2
に代入されます。b3 = x == y
:b3
の型は型推論によって決定されます。この場合、文脈が特定のboolean型を要求しないため、x == y
の結果はデフォルトのbool
型として型付けされ、b3
もbool
型になります。
この変更は、Go言語の型システムにおける型なし定数の概念を、比較演算の結果にも一貫して適用することで、言語の挙動をより予測可能で柔軟なものにしています。これにより、開発者はカスタム型をより自然に利用できるようになります。
また、定数に関するセクション(Constants
)においても、以下の記述が修正されています。
変更前:
A constant comparison always yields an untyped boolean constant.
変更後:
A constant comparison always yields an untyped boolean constant.
一見すると変更がないように見えますが、これは既存の記述がこの新しい挙動と矛盾しないことを確認するためのものです。重要なのは、このコミットが仕様書全体で比較結果の型に関する記述を一貫させ、型なしのboolean定数としての扱いを明確にした点です。
さらに、仕様書内のコード例における変数名の修正(foo_bar
からfooBar
へ)は、Go言語のコーディングスタイルガイドラインへの準拠を徹底するためのものです。これは技術的な機能変更ではありませんが、ドキュメントの品質と一貫性を高める上で重要です。
コアとなるコードの変更箇所
このコミットによる変更は、Go言語の仕様書であるdoc/go_spec.html
ファイルに集中しています。
主な変更点は以下の通りです。
-
比較演算子の結果の型に関する記述の修正:
id="Comparison_operators"
セクションの記述が変更されました。- 変更前:
Comparison operators compare two operands and yield a value of type <code>bool</code>.
- 変更後:
Comparison operators compare two operands and yield a 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> <pre> type MyBool bool var x, y int var ( b1 MyBool = x == y // result of comparison has type MyBool b2 bool = x == y // result of comparison has type bool b3 = x == y // result of comparison has type bool ) </pre>
-
定数に関する記述の修正:
id="Constants"
セクションにおいて、バイナリ演算子の結果の型に関する記述が修正されました。- 変更前:
different kinds of untyped constants, the operation and result use
- 変更後:
different kinds of untyped constants, the operation and, for non-boolean operations, the result use
- これは、非boolean演算の場合にのみ結果の型が決定されることを明確にしています。比較演算(boolean演算)の結果は常に型なしのboolean定数であるため、この修正は一貫性を保つためのものです。
- 変更前:
-
コードフラグメント内の変数名の修正(スネークケースからキャメルケースへ):
reply_chan
->replyChan
chan_ptr
->chanPtr
is_int
->isInt
is_float64
->isFloat64
is_func
->isFunc
is_bool
->isBool
is_string
->isString
no_result
->noResult
simple_f
->simpleF
complex_f1
->complexF1
complex_f2
->complexF2
complex_f3
->complexF3
-
仕様書のバージョン日付の更新:
Subtitle
がVersion of February 16, 2012
からVersion of February 21, 2012
に更新されました。
これらの変更は、Go言語の仕様の正確性を高め、Goのコーディング規約に沿ったドキュメントの品質を維持することを目的としています。
コアとなるコードの解説
このコミットのコアとなる変更は、Go言語の仕様書(doc/go_spec.html
)における比較演算子の結果の型に関する記述の修正と、それに関連するコード例の追加です。
以前の仕様では、比較演算の結果は単純にbool
型であるとされていました。しかし、Go言語の型なし定数の概念を考慮すると、この記述は不十分であり、特にカスタムのboolean型を使用する際に混乱を招く可能性がありました。
新しい記述では、比較演算の結果が「boolean値」を生成し、その結果は「任意のboolean型に代入可能」であると明確にされています。そして、「文脈が特定のboolean型を要求しない場合、結果はbool
型となる」という補足が加えられています。
これは、Goコンパイラが比較演算の結果を「型なしのboolean定数」として扱うことを意味します。型なし定数は、代入先の変数の型や、式が使用される文脈に基づいて型付けされます。この柔軟性により、開発者は以下のようなコードをより自然に記述できるようになります。
type MyBool bool
func main() {
var a, b int = 10, 20
// 比較結果がMyBool型に型付けされる
var myBoolVar MyBool = a < b
// 比較結果がbool型に型付けされる
var boolVar bool = a == b
// 型推論によりbool型となる
inferredVar := a > b
}
この変更は、Go言語の型システムの一貫性を向上させ、型なし定数の概念をより広範な文脈に適用することで、言語の設計思想をより明確に反映しています。これにより、Goのコードはより予測可能になり、開発者は型に関する挙動をより深く理解できるようになります。
また、仕様書内のコード例でスネークケース(foo_bar
)からキャメルケース(fooBar
)への変数名変更は、Go言語の公式コーディング規約への準拠を徹底するためのものです。これは機能的な変更ではありませんが、ドキュメントの品質とGoコミュニティ全体でのコードスタイルの一貫性を保つ上で非常に重要です。Goでは、エクスポートされない識別子にはlowerCamelCaseが推奨されており、仕様書内のコード例もこの慣習に従うべきであるという考えに基づいています。
これらの変更は、Go言語の仕様が進化し、より正確で、よりGoらしい慣習を反映するように継続的に改善されていることを示しています。
関連リンク
- Go言語の公式ドキュメント: https://go.dev/
- Go言語の仕様書: https://go.dev/ref/spec
- Go言語のIssue #2561:
x == y
should be an untyped boolean constant (このコミットが修正したIssue)- 残念ながら、古いGoのIssueトラッカーのリンクは直接アクセスできない場合があります。しかし、このIssueはGoの型システムにおける比較演算子の結果の型に関する議論の重要な一部でした。
- Go CL 5671096: https://golang.org/cl/5671096 (このコミットに対応するGerritの変更リスト)
参考にした情報源リンク
- Go言語の公式ドキュメント(特に「Constants」と「Comparison operators」のセクション)
- Go言語のIssueトラッカー(Issue #2561に関する議論)
- Go言語のコーディングスタイルガイドライン(変数名の命名規則に関する情報)
- Go言語の型システムに関する一般的な解説記事やチュートリアル