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

[インデックス 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)への大幅な改定を含んでいます。主要な変更点は以下の通りです:

  1. 仕様書の日付更新: 2008年10月24日から10月28日に更新
  2. Todo/Issuesリストの整理: 完了したタスクの移動、新しい課題の追加
  3. プラットフォーム依存型の根本的な再設計: エイリアスベースから独立型ベースへの移行
  4. new関数の配列容量指定機能の追加: 第3引数としての容量指定機能の文書化

変更の背景

言語設計の初期段階での重要な決定

2008年は、Go言語の設計がRobert Griesemer、Rob Pike、Ken Thompsonによって活発に進められていた時期です。この時期の言語仕様は「DRAFT」段階で、多くの基本的な設計決定が行われていました。

プラットフォーム依存型の設計課題

初期のGo言語設計では、C言語のような多数のプラットフォーム依存型エイリアス(shortlongdoubleなど)が存在していました。しかし、これらのエイリアスは以下の問題を抱えていました:

  1. ポータビリティの問題: 異なるプラットフォーム間での型の互換性
  2. 型安全性の欠如: エイリアス関係による意図しない型変換
  3. C言語からの複雑性の継承: 複雑な型階層の持ち込み

new関数の機能拡張の必要性

初期のnew関数は基本的なメモリ割り当てのみを行っていましたが、配列やスライスの効率的な初期化のために、長さと容量を同時に指定する機能が求められていました。

前提知識の解説

Go言語の型システム

Go言語は静的型付け言語で、コンパイル時に型チェックが行われます。Go言語の型システムの特徴:

  1. 型の明示的変換: 異なる型間の変換は明示的に行う必要がある
  2. 構造的型付け: インターフェースは構造的に一致すれば実装される
  3. 型の等価性: 型の名前が異なれば、同じ基底型でも異なる型として扱われる

プラットフォーム依存型の概念

プラットフォーム依存型は、実行環境(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

型変換の新しい要件

新しい型システムでは、byteuint8の関係を除き、すべての数値型は異なる型として扱われます:

// 新しい型システムでの例
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言語は以下の重要な特徴を獲得しました:

  1. 型安全性の向上: 異なる型間の明示的変換を強制することで、意図しない型変換を防止
  2. ポータビリティの確保: プラットフォーム依存型とプラットフォーム非依存型の明確な分離
  3. 複雑性の削減: C言語から継承した複雑な型階層の排除

new関数の容量指定機能

この機能により、配列の初期化時に長さと容量を個別に指定できるようになりました:

// 長さ0、容量1024のスライス
bp := new([]byte, 0, 1024)

// 従来の方法との比較
traditional := make([]byte, 0, 1024)  // 後のmake関数での実装

ただし、コミット内のコメントでは、この機能に対する設計者の懸念も記録されています:

  1. 多次元配列での制約: 将来的な多次元配列対応を困難にする可能性
  2. 代替手段の存在: new(T, c)[0 : l]による同等の機能実現
  3. 最適化の複雑さ: コンパイラ最適化の複雑化

関連リンク

参考にした情報源リンク

  1. Go: A Documentary - The golang.design Initiative
  2. Go (programming language) - Wikipedia
  3. The Go Programming Language Specification
  4. Go Type System Overview - Go 101
  5. Understanding Data Types in Go | DigitalOcean
  6. Performance - What are the advantages of the general types (int / uint) over specific types (int64 / uint64) in Go lang? - Stack Overflow
  7. Golang Make Function - Initializing Slices, Maps, and Channels
  8. Arrays, slices (and strings): The mechanics of 'append' - The Go Programming Language