[インデックス 15679] ファイルの概要
このコミットは、Go言語の仕様書(doc/go_spec.html
)における、配列やスライスのインデックス、およびmake
組み込み関数の引数に関する型要件の記述を明確にするものです。具体的には、「整数値(integer value)」である必要があった箇所を、「整数型(integer type)または型なし(untyped)」である必要がある、と修正しています。これにより、Go言語の型システムにおけるインデックスやサイズ引数の扱いがより厳密かつ正確に定義されました。
コミット
commit b66df0e9bad6b9dca4935a5128b2f696156c2d8a
Author: Robert Griesemer <gri@golang.org>
Date: Mon Mar 11 09:20:52 2013 -0700
spec: typed indices must be of integer type
The same rules apply for make arguments.
R=r, rsc, iant, ken
CC=golang-dev
https://golang.org/cl/7656043
GitHub上でのコミットページへのリンク
https://github.com/golang/go/commit/b66df0e9bad6b9dca4935a5128b2f696156c2d8a
元コミット内容
spec: typed indices must be of integer type
The same rules apply for make arguments.
R=r, rsc, iant, ken
CC=golang-dev
https://golang.org/cl/7656043
変更の背景
このコミットの背景には、Go言語の仕様における型システムの厳密性と一貫性の追求があります。Go言語では、配列やスライスへのアクセス、およびmake
関数によるチャネル、マップ、スライスの作成時に、そのサイズやインデックスを指定する必要があります。これらの値がどのような型を持つべきかについて、以前の仕様では「integer value(整数値)」と記述されていました。
しかし、「整数値」という表現は、Goの型システムにおける「型付き(typed)」と「型なし(untyped)」の概念を考慮すると、曖昧さを生む可能性がありました。特に、型なしの定数(例: 100
)は、その文脈に応じて様々な整数型に変換されうるため、単に「整数値」とだけ記述すると、コンパイラの実装や開発者の解釈に揺らぎが生じる恐れがありました。
このコミットは、この曖昧さを解消し、インデックスやmake
の引数として許容される値の型をより正確に定義することを目的としています。具体的には、「整数型(integer type)」または「型なし(untyped)」のいずれかであることを明記することで、Go言語の設計思想である型安全性と明確性を向上させています。これにより、コンパイラはより厳密な型チェックを行うことができ、開発者はコードの意図をより正確に理解できるようになります。
前提知識の解説
このコミットを理解するためには、Go言語の以下の基本的な概念を理解しておく必要があります。
1. Go言語の型システム
Go言語は静的型付け言語であり、変数は宣言時に型を持ちます。型は、その変数が保持できる値の種類と、その値に対して実行できる操作を決定します。
2. 整数型 (Integer Types)
Go言語には、符号付き整数型(int8
, int16
, int32
, int64
, int
)と符号なし整数型(uint8
, uint16
, uint32
, uint64
, uint
)があります。int
とuint
は、システムに依存するサイズ(通常は32ビットまたは64ビット)を持ちます。
3. 型なし定数 (Untyped Constants)
Go言語には「型なし定数」という概念があります。これは、リテラル(例: 100
, 3.14
, "hello"
)や定数式の結果として生成される値で、まだ特定のGoの型に関連付けられていないものです。型なし定数は、その値が使用される文脈(代入、演算など)に基づいて、適切な型に「デフォルト型付け」されます。例えば、型なしの整数定数100
は、var x int = 100
のようにint
型の変数に代入されるとint
型になります。
4. 配列とスライス (Arrays and Slices)
- 配列: 固定長で、同じ型の要素のシーケンスです。配列の要素には、
a[index]
のように整数インデックスを使ってアクセスします。 - スライス: 可変長で、配列の一部を参照するデータ構造です。スライスも配列と同様に、整数インデックスを使って要素にアクセスします。
5. len()
組み込み関数
len()
関数は、配列、スライス、文字列、マップ、チャネルの長さを返します。配列やスライスのインデックスは、0
からlen(a) - 1
の範囲でなければなりません。
6. make()
組み込み関数
make()
関数は、スライス、マップ、チャネルといった組み込みの参照型を初期化するために使用されます。
- スライスの場合:
make([]T, len, cap)
-len
はスライスの初期長、cap
は容量を指定します。 - マップの場合:
make(map[K]V, cap)
-cap
はマップの初期容量を指定します。 - チャネルの場合:
make(chan T, cap)
-cap
はチャネルのバッファサイズを指定します。
これらのlen
, cap
引数は、通常、整数値を期待します。
技術的詳細
このコミットの技術的な詳細は、Go言語のコンパイラとランタイムが、配列/スライスのインデックスおよびmake
関数のサイズ引数をどのように解釈し、処理するかという点にあります。
以前の仕様では、これらの引数が「integer value(整数値)」であるとされていました。これは、一見すると問題ないように思えますが、Goの型なし定数の概念と組み合わせると、潜在的な曖昧さを生じさせます。
例えば、以下のようなコードを考えます。
var s []int
s = make([]int, 10) // ここでの '10' は型なし整数定数
s[5] = 100 // ここでの '5' も型なし整数定数
この場合、10
や5
は型なし整数定数であり、文脈によってint
型にデフォルト型付けされます。しかし、もしこれらの値が明示的に異なる整数型(例: int32(5)
)であった場合、以前の「integer value」という記述では、それが許容されるのかどうかが明確ではありませんでした。
このコミットは、この点を明確にするために、仕様を「integer type(整数型)または untyped(型なし)」と修正しました。
- 「integer type(整数型)」: これは、
int
,int8
,uint64
などのGoの具体的な整数型を持つ値を指します。これにより、明示的に型付けされた整数値がインデックスやサイズ引数として使用できることが明確になります。 - 「untyped(型なし)」: これは、型なし整数定数を指します。型なし定数は、その値が使用される文脈で適切な整数型に変換されるため、これも許容されるべきです。
この変更により、Go言語のコンパイラは、インデックスやmake
の引数として渡される値が、厳密に整数型であるか、または整数型に変換可能な型なし定数であるかをチェックするようになります。これにより、以下のようなメリットが生まれます。
- 型安全性と堅牢性の向上: 不適切な型の値がインデックスやサイズ引数として使用されることを防ぎ、実行時エラーのリスクを低減します。
- 仕様の明確化: 言語仕様の記述がより正確になり、コンパイラの実装者や言語のユーザーにとっての解釈のブレがなくなります。
- 一貫性の確保: Goの型システム全体における「型付き」と「型なし」の概念との一貫性が保たれます。
この修正は、Go言語の初期段階における仕様の洗練の一環であり、言語の安定性と信頼性を高める上で重要な役割を果たしています。
コアとなるコードの変更箇所
このコミットでは、doc/go_spec.html
ファイルが変更されています。以下にその差分を示します。
--- a/doc/go_spec.html
+++ b/doc/go_spec.html
@@ -2513,7 +2513,8 @@ rules apply:
If <code>a</code> is not a map:
</p>
<ul>
- <li>the index <code>x</code> must be an integer value; it is <i>in range</i> if <code>0 <= x < len(a)</code>,
+ <li>the index <code>x</code> must be of integer type or untyped;
+ it is <i>in range</i> if <code>0 <= x < len(a)</code>,
\t otherwise it is <i>out of range</i></li>
\t<li>a <a href=\"#Constants\">constant</a> index must be non-negative
\t and representable by a value of type <code>int</code>
@@ -5095,7 +5096,7 @@ make(T, n) channel asynchronous channel of type T, buffer size n
\n \n <p>\n-The size arguments <code>n</code> and <code>m</code> must be integer values.\n+The size arguments <code>n</code> and <code>m</code> must be of integer type or untyped.\n A <a href=\"#Constants\">constant</a> size argument must be non-negative and\n representable by a value of type <code>int</code>.\n If both <code>n</code> and <code>m</code> are provided and are constant, then\n```
## コアとなるコードの解説
変更はGo言語の仕様書(HTML形式)内の2箇所で行われています。
### 1. 配列/スライスのインデックスに関する記述
```diff
- <li>the index <code>x</code> must be an integer value; it is <i>in range</i> if <code>0 <= x < len(a)</code>,
+ <li>the index <code>x</code> must be of integer type or untyped;
+ it is <i>in range</i> if <code>0 <= x < len(a)</code>,
- 変更前:
the index <code>x</code> must be an integer value;
- インデックス
x
が「整数値」でなければならない、と記述されていました。
- インデックス
- 変更後:
the index <code>x</code> must be of integer type or untyped;
- インデックス
x
が「整数型」または「型なし」でなければならない、と修正されました。 - これにより、
int
,int32
などの具体的な整数型を持つ変数や、10
,0xFF
のような型なし整数定数がインデックスとして許容されることが明確になりました。
- インデックス
2. make
関数のサイズ引数に関する記述
-The size arguments <code>n</code> and <code>m</code> must be integer values.
+The size arguments <code>n</code> and <code>m</code> must be of integer type or untyped.
- 変更前:
The size arguments <code>n</code> and <code>m</code> must be integer values.
make
関数のサイズ引数n
とm
が「整数値」でなければならない、と記述されていました。
- 変更後:
The size arguments <code>n</code> and <code>m</code> must be of integer type or untyped.
- サイズ引数
n
とm
が「整数型」または「型なし」でなければならない、と修正されました。 - これもインデックスの変更と同様に、
make
関数に渡すスライス長、マップ容量、チャネルバッファサイズなどの引数について、許容される型の範囲を明確にしています。
- サイズ引数
これらの変更は、Go言語の型システムにおける「型付き」と「型なし」の概念を、言語仕様の具体的な記述に反映させることで、より正確で厳密な定義を提供しています。
関連リンク
- Go Change List (CL) 7656043: https://golang.org/cl/7656043
- このコミットに対応するGoの変更提案(Change List)です。詳細な議論やレビューの履歴が含まれている可能性があります。
参考にした情報源リンク
- Go言語の公式ドキュメント: https://go.dev/
- Go言語仕様: https://go.dev/ref/spec
- 特に「Types」, 「Constants」, 「Array types」, 「Slice types」, 「Built-in functions」のセクションが関連します。
- Go言語の型なし定数に関する解説記事 (一般的な情報源):
- "Untyped constants in Go": https://go.dev/blog/constants (これは一般的なGoのブログ記事であり、直接このコミットに言及しているわけではありませんが、型なし定数の概念を理解する上で非常に役立ちます。)
- Go言語の型システムに関する一般的なチュートリアルやドキュメント。
- (Web検索で「Go untyped constants」や「Go integer types」などで検索して得られる情報)
- 例: https://www.ardanlabs.com/blog/2013/07/understanding-go-constants.html (Ardan Labsのブログ記事など、Goの定数に関する詳細な解説)
- 例: https://yourbasic.org/golang/untyped-constants/ (Goの型なし定数に関する簡潔な解説)