[インデックス 1005] ファイルの概要
このコミットは、Go言語の初期開発段階(2008年)において、言語仕様の数値型システムとnew
関数の仕様を重要な方向性で改定したものです。Robert Griesemer氏による変更は、Go言語の型システムの基盤となる設計思想を確立する重要な節目となりました。
コミット
- コミットハッシュ: ebf14c625dcd4b02bb4b6575bf8312ca1d8d1cc5
- 作成者: Robert Griesemer gri@golang.org
- 日付: 2008年10月30日 14:50:23 (PDT)
- コミットメッセージ:
- 数値型セクションの明確化:プラットフォーム依存型がプラットフォーム非依存型とは異なる(単なるエイリアスではない)ことを明記(byte, uint8を除く)
new(a, len, cap)
の欠落していたドキュメントを追加- todo/issuesリストを更新
GitHub上でのコミットページへのリンク
https://github.com/golang/go/commit/ebf14c625dcd4b02bb4b6575bf8312ca1d8d1cc5
元コミット内容
このコミットは、Go言語仕様書(doc/go_spec.txt
)への大幅な改定を含んでいます。主要な変更点は以下の通りです:
- 仕様書の日付更新: 2008年10月24日から10月28日に更新
- Todo/Issuesリストの整理: 完了したタスクの移動、新しい課題の追加
- プラットフォーム依存型の根本的な再設計: エイリアスベースから独立型ベースへの移行
new
関数の配列容量指定機能の追加: 第3引数としての容量指定機能の文書化
変更の背景
言語設計の初期段階での重要な決定
2008年は、Go言語の設計がRobert Griesemer、Rob Pike、Ken Thompsonによって活発に進められていた時期です。この時期の言語仕様は「DRAFT」段階で、多くの基本的な設計決定が行われていました。
プラットフォーム依存型の設計課題
初期のGo言語設計では、C言語のような多数のプラットフォーム依存型エイリアス(short
、long
、double
など)が存在していました。しかし、これらのエイリアスは以下の問題を抱えていました:
- ポータビリティの問題: 異なるプラットフォーム間での型の互換性
- 型安全性の欠如: エイリアス関係による意図しない型変換
- C言語からの複雑性の継承: 複雑な型階層の持ち込み
new
関数の機能拡張の必要性
初期のnew
関数は基本的なメモリ割り当てのみを行っていましたが、配列やスライスの効率的な初期化のために、長さと容量を同時に指定する機能が求められていました。
前提知識の解説
Go言語の型システム
Go言語は静的型付け言語で、コンパイル時に型チェックが行われます。Go言語の型システムの特徴:
- 型の明示的変換: 異なる型間の変換は明示的に行う必要がある
- 構造的型付け: インターフェースは構造的に一致すれば実装される
- 型の等価性: 型の名前が異なれば、同じ基底型でも異なる型として扱われる
プラットフォーム依存型の概念
プラットフォーム依存型は、実行環境(32ビット/64ビット)によってサイズが変わる型です:
- 32ビット環境:
int
は通常32ビット - 64ビット環境:
int
は通常64ビット
これにより、プラットフォーム最適化とポータビリティの両方を実現します。
new
関数の役割
new
関数は、指定された型のゼロ値で初期化されたメモリを割り当て、そのポインタを返します。Go言語では、ガベージコレクションにより自動的にメモリ管理が行われます。
技術的詳細
型システムの変更の詳細
削除された型エイリアス
// 削除された型
byte, ushort, uint, ulong, short, int, long, float, double, ptrint
// 具体的な削除例
ushort uint16 <= ushort <= uint
uint uint32 <= uint <= ulong
ulong uint64 <= ulong
short int16 <= short <= int
int int32 <= int <= long
long int64 <= long
float float32 <= float <= double
double float64 <= double
新しい型システム
// プラットフォーム非依存型
byte same as uint8 (for convenience)
uint8 the set of all unsigned 8-bit integers
uint16 the set of all unsigned 16-bit integers
uint32 the set of all unsigned 32-bit integers
uint64 the set of all unsigned 64-bit integers
int8 the set of all signed 8-bit integers
int16 the set of all signed 16-bit integers
int32 the set of all signed 32-bit integers
int64 the set of all signed 64-bit integers
float32 the set of all valid IEEE-754 32-bit floating point numbers
float64 the set of all valid IEEE-754 64-bit floating point numbers
float80 the set of all valid IEEE-754 80-bit floating point numbers
// プラットフォーム依存型
uint at least 32 bits, at most the size of the largest uint type
int at least 32 bits, at most the size of the largest int type
float at least 32 bits, at most the size of the largest float type
uintptr smallest uint type large enough to store the uninterpreted bits of a pointer value
型変換の新しい要件
新しい型システムでは、byte
とuint8
の関係を除き、すべての数値型は異なる型として扱われます:
// 新しい型システムでの例
var a int32 = 42
var b int = 42
// a と b は同じ値でも異なる型のため、直接代入不可
// 明示的な変換が必要
b = int(a) // 明示的変換が必要
new
関数の拡張
従来のnew
関数
new(type, [optional list of expressions])
新しい配列容量指定機能
// 配列の容量を指定する第3引数
bp := new([]byte, 0, 1024); // 長さ0、容量1024の空の配列へのポインタ
コアとなるコードの変更箇所
1. 型システムの基本定義(doc/go_spec.txt:610-650行)
変更前:
- all basic types:
bool, uint8, uint16, uint32, uint64, int8, int16, int32, int64,
float32, float64, float80, string
- and their alias types:
byte, ushort, uint, ulong, short, int, long, float, double, ptrint
変更後:
- all basic types:
bool, byte, uint8, uint16, uint32, uint64, int8, int16, int32, int64,
float32, float64, float80, string
- a set of platform-specific convenience types:
uint, int, float, uintptr
2. 算術型の詳細定義(doc/go_spec.txt:877-165行)
変更前の複雑な型階層:
The integer sizes are defined such that short is at least 16 bits, int
is at least 32 bits, and long is at least 64 bits (and ditto for the
unsigned equivalents). Also, the sizes are such that short <= int <=
long. Similarly, float is at least 32 bits, double is at least 64
bits, and the sizes have float <= double.
変更後のシンプルな定義:
The following list enumerates all platform-independent numeric types:
byte same as uint8 (for convenience)
uint8 the set of all unsigned 8-bit integers
[...]
Additionally, Go declares a set of platform-specific numeric types for convenience:
uint at least 32 bits, at most the size of the largest uint type
int at least 32 bits, at most the size of the largest int type
float at least 32 bits, at most the size of the largest float type
uintptr smallest uint type large enough to store the uninterpreted bits of a pointer value
3. new
関数の配列容量指定(doc/go_spec.txt:2724-2745行)
変更前:
new(type, [optional list of expressions])
変更後:
new(type [, optional list of expressions])
For arrays, a third argument may be provided to specify the array capacity:
bp := new([]byte, 0, 1024); # a pointer to an empty open array with capacity 1024
コアとなるコードの解説
型システム変更の意義
この変更により、Go言語は以下の重要な特徴を獲得しました:
- 型安全性の向上: 異なる型間の明示的変換を強制することで、意図しない型変換を防止
- ポータビリティの確保: プラットフォーム依存型とプラットフォーム非依存型の明確な分離
- 複雑性の削減: C言語から継承した複雑な型階層の排除
new
関数の容量指定機能
この機能により、配列の初期化時に長さと容量を個別に指定できるようになりました:
// 長さ0、容量1024のスライス
bp := new([]byte, 0, 1024)
// 従来の方法との比較
traditional := make([]byte, 0, 1024) // 後のmake関数での実装
ただし、コミット内のコメントでは、この機能に対する設計者の懸念も記録されています:
- 多次元配列での制約: 将来的な多次元配列対応を困難にする可能性
- 代替手段の存在:
new(T, c)[0 : l]
による同等の機能実現 - 最適化の複雑さ: コンパイラ最適化の複雑化
関連リンク
参考にした情報源リンク
- Go: A Documentary - The golang.design Initiative
- Go (programming language) - Wikipedia
- The Go Programming Language Specification
- Go Type System Overview - Go 101
- Understanding Data Types in Go | DigitalOcean
- Performance - What are the advantages of the general types (int / uint) over specific types (int64 / uint64) in Go lang? - Stack Overflow
- Golang Make Function - Initializing Slices, Maps, and Channels
- Arrays, slices (and strings): The mechanics of 'append' - The Go Programming Language