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

[インデックス 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)があります。intuintは、システムに依存するサイズ(通常は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' も型なし整数定数

この場合、105は型なし整数定数であり、文脈によってint型にデフォルト型付けされます。しかし、もしこれらの値が明示的に異なる整数型(例: int32(5))であった場合、以前の「integer value」という記述では、それが許容されるのかどうかが明確ではありませんでした。

このコミットは、この点を明確にするために、仕様を「integer type(整数型)または untyped(型なし)」と修正しました。

  • 「integer type(整数型)」: これは、int, int8, uint64などのGoの具体的な整数型を持つ値を指します。これにより、明示的に型付けされた整数値がインデックスやサイズ引数として使用できることが明確になります。
  • 「untyped(型なし)」: これは、型なし整数定数を指します。型なし定数は、その値が使用される文脈で適切な整数型に変換されるため、これも許容されるべきです。

この変更により、Go言語のコンパイラは、インデックスやmakeの引数として渡される値が、厳密に整数型であるか、または整数型に変換可能な型なし定数であるかをチェックするようになります。これにより、以下のようなメリットが生まれます。

  1. 型安全性と堅牢性の向上: 不適切な型の値がインデックスやサイズ引数として使用されることを防ぎ、実行時エラーのリスクを低減します。
  2. 仕様の明確化: 言語仕様の記述がより正確になり、コンパイラの実装者や言語のユーザーにとっての解釈のブレがなくなります。
  3. 一貫性の確保: 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 &lt;= x &lt; 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 &lt;= x &lt; 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 &lt;= x &lt; 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 &lt;= x &lt; 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関数のサイズ引数nmが「整数値」でなければならない、と記述されていました。
  • 変更後: The size arguments <code>n</code> and <code>m</code> must be of integer type or untyped.
    • サイズ引数nmが「整数型」または「型なし」でなければならない、と修正されました。
    • これもインデックスの変更と同様に、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言語の型なし定数に関する解説記事 (一般的な情報源):