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

[インデックス 1247] ファイルの概要

このコミットは、Go言語の初期開発段階において、src/lib/container/vector.go ファイルとその関連エントリを削除するものです。具体的には、src/lib/Makefile から vector への参照が削除され、src/lib/container/vector.go ファイル自体が完全に削除されています。

コミット

commit 480b962df52aa8caebb2fdaf1eb331584ccc9ce7
Author: Robert Griesemer <gri@golang.org>
Date:   Tue Nov 25 10:08:49 2008 -0800

    - delete vector.go - not needed anymore
    - runs all.bash
    
    R=r
    DELTA=121  (0 added, 121 deleted, 0 changed)
    OCL=19960
    CL=19983

GitHub上でのコミットページへのリンク

https://github.com/golang/go/commit/480b962df52aa8caebb2fdaf1eb331584ccc9ce7

元コミット内容

vector.go ファイルが不要になったため削除されました。この変更後、all.bash スクリプトが実行されています。

変更の背景

このコミットは、Go言語の初期開発フェーズ、特にGo 1.0リリース前の2008年に行われたものです。Go言語は当初から、動的な配列の概念を「スライス(slices)」として言語に組み込むことを目指していました。container/vector パッケージは、Go言語にスライスが導入される前の過渡期に、動的な配列機能を提供するために存在していました。

Go言語の設計思想として、言語のコア機能はシンプルに保ち、複雑なデータ構造は標準ライブラリで提供するというものがあります。しかし、スライスはあまりにも基本的なデータ構造であり、言語レベルでサポートすることで、より効率的で慣用的なコード記述が可能になると判断されました。

このコミットが行われた時期には、Go言語のスライスが十分に成熟し、container/vector パッケージが提供していた機能を完全に代替できるようになったため、冗長となった vector.go を削除する決定がなされました。これにより、Go言語の標準ライブラリから重複する機能が排除され、スライスへの移行が促進されました。

前提知識の解説

Go言語の初期開発

Go言語は、GoogleでRobert Griesemer、Rob Pike、Ken Thompsonによって設計され、2009年に一般公開されました。その設計目標には、効率的なコンパイル、並行処理の容易さ、そして現代的なプログラミングパラダイムへの対応が含まれていました。初期のGoは、現在のGoとは異なる部分も多く、言語仕様や標準ライブラリは活発に進化していました。このコミットは、その進化の過程で、より良い設計へと向かうための重要な一歩でした。

動的配列とVector

プログラミングにおける「動的配列」とは、実行時にサイズを変更できる配列のことです。多くの言語で、この概念は「リスト」「アレイリスト」「ベクター」などの名前で提供されます。C++のstd::vectorがその代表例です。これらは通常、要素の追加や削除に応じて内部的にメモリを再割り当てすることで、動的なサイズ変更を実現します。

Go言語のスライス (Slices)

Go言語におけるスライスは、配列のセグメント(部分)を参照する軽量なデータ構造です。スライスは、基となる配列へのポインタ、長さ(len)、容量(cap)の3つの要素で構成されます。スライスは動的なサイズ変更が可能であり、append関数によって要素を追加したり、スライス式によって部分スライスを作成したりできます。

スライスはGo言語の非常に強力で中心的な機能であり、動的配列のほとんどのユースケースを効率的にカバーします。container/vectorパッケージが提供していた機能は、Goのスライスと組み込み関数(make, len, cap, appendなど)によって、より効率的かつ慣用的に実現できるようになりました。

技術的詳細

このコミットの技術的な詳細としては、主に以下の点が挙げられます。

  1. container/vector パッケージの廃止: src/lib/container/vector.go は、Go言語がスライスを言語機能として完全に統合する前に、動的配列の機能を提供していたパッケージです。このパッケージは、Vector 型を定義し、Init, New, Len, At, Set, Remove, Reset, Insert, Append などのメソッドを通じて、動的配列の基本的な操作を提供していました。 コミットの差分を見ると、vector.go の全コード(124行)が削除されていることがわかります。これは、このパッケージが完全に不要になったことを意味します。

  2. Makefile の更新: src/lib/Makefile は、Go言語の標準ライブラリのビルドプロセスを管理するファイルです。このファイルには、ビルド対象となるディレクトリやファイルのリストが含まれています。vector パッケージが削除されたため、Makefile 内の DIRS 変数から vector への参照が削除されました。これにより、ビルドシステムが削除されたパッケージをビルドしようとすることがなくなり、クリーンなビルドプロセスが維持されます。

この変更は、Go言語の設計における重要な転換点を示しています。Goは、C++のような言語が提供する汎用的なコンテナライブラリ(例: std::vector)とは異なり、スライスという言語組み込みの強力なプリミティブを提供することで、よりシンプルで効率的なデータ構造の操作を可能にしました。container/vector の削除は、この設計思想が初期段階で確立され、実装に反映された証拠と言えます。

コアとなるコードの変更箇所

このコミットによる変更は以下の2ファイルです。

  1. src/lib/Makefile:

    --- a/src/lib/Makefile
    +++ b/src/lib/Makefile
    @@ -24,7 +24,6 @@ DIRS=\
     FILES=\
      	bignum\
      	bufio\
    -	vector\
      	flag\
      	once\
      	rand\
    
  2. src/lib/container/vector.go: このファイルは完全に削除されました。差分では全行が削除として表示されています。

    --- a/src/lib/container/vector.go
    +++ /dev/null
    @@ -1,124 +0,0 @@
    -// Copyright 2009 The Go Authors. All rights reserved.
    -// Use of this source code is governed by a BSD-style
    -// license that can be found in the LICENSE file.
    -
    -package vector
    -
    -//export Vector, New;
    -
    -/*
    -	import vector "vector"
    -	v := vector.New();
    -	v.Insert(0, new(Foo));
    -	v.Append(new(Foo));
    -	v.Remove(0);\
    -	for i := 0; i < v.Len(); i++ { f(v.At(i)); }\
    -*/
    -
    -type Element interface {
    -}
    -
    -
    -
    -export type Vector struct {
    -	elem *[]Element;
    -}
    -
    -
    -func (v *Vector) Init() {
    -	v.elem = new([]Element, 8) [0 : 0];  // capacity must be > 0!
    -}
    -
    -
    -export func New() *Vector {
    -	v := new(Vector);
    -	v.Init();
    -	return v;
    -}
    -
    -
    -func (v *Vector) Len() int {
    -	return len(v.elem);
    -}
    -
    -
    -func (v *Vector) At(i int) Element {
    -	return v.elem[i];
    -}
    -
    -
    -func (v *Vector) Set(i int, e Element) {
    -	v.elem[i] = e;
    -}
    -
    -
    -func (v *Vector) Remove(i int) Element {
    -	ret := v.elem[i];
    -	n := v.Len();
    -	for j := i + 1; j < n; j++ {
    -		v.elem[j - 1] = v.elem[j];
    -	}
    -	v.elem[n - 1] = nil;  // support GC, nil out entry
    -	v.elem = v.elem[0 : n - 1];
    -	return ret;
    -}
    -
    -
    -func (v *Vector) Reset() {
    -	// support GC, nil out entries
    -	for j := len(v.elem) - 1; j >= 0; j-- {
    -		v.elem[j] = nil;
    -	}
    -	v.elem = v.elem[0:0];
    -}
    -
    -func (v *Vector) Insert(i int, e Element) {
    -	n := v.Len();
    -
    -	// grow array by doubling its capacity
    -	if n == cap(v.elem) {
    -		a := new([]Element, n*2);
    -		for j := 0; j < n; j++ {
    -			a[j] = v.elem[j];
    -		}
    -		v.elem = a;
    -	}
    -
    -	// make a hole
    -	v.elem = v.elem[0 : n + 1];
    -	for j := n; j > i; j-- {
    -		v.elem[j] = v.elem[j-1];
    -	}
    -	
    -	v.elem[i] = e;
    -}
    -
    -
    -func (v *Vector) Append(e Element) {
    -	v.Insert(len(v.elem), e);
    -}
    -
    -
    -/*
    -type I struct { val int; };  // BUG: can\'t be local;
    -
    -func Test() {
    -	i0 := new(I); i0.val = 0;
    -	i1 := new(I); i1.val = 11;
    -	i2 := new(I); i2.val = 222;
    -	i3 := new(I); i3.val = 3333;
    -	i4 := new(I); i4.val = 44444;
    -	v := New();
    -	print("hi\n");
    -	v.Insert(0, i4);
    -	v.Insert(0, i3);
    -	v.Insert(0, i2);
    -	v.Insert(0, i1);
    -	v.Insert(0, i0);
    -	for i := 0; i < v.Len(); i++ {
    -		x := convert(*I, v.At(i));
    -		print(i, " ", v.At(i).(*I).val, "\n");
    -	}
    -}
    -
    -export Test;
    -*/
    

コアとなるコードの解説

src/lib/Makefile の変更

src/lib/Makefile から - vector\ の行が削除されています。これは、Goの標準ライブラリをビルドする際に、もはや container/vector パッケージをコンパイル対象としないことを意味します。これにより、ビルドシステムから不要な依存関係が取り除かれ、ビルド時間が短縮され、コードベースが整理されます。

src/lib/container/vector.go の削除

このファイルは、Go言語がスライスを導入する以前に、動的配列の機能を提供するために存在していました。ファイルの内容を見ると、Vector という型が定義されており、Init, New, Len, At, Set, Remove, Insert, Append といった、一般的な動的配列(ベクター)が持つべきメソッドが実装されていたことがわかります。

特に注目すべきは、Insert メソッド内で配列の容量が不足した場合に、新しいより大きな配列を作成し、既存の要素をコピーして容量を倍増させるロジック(if n == cap(v.elem) { a := new([]Element, n*2); ... })が実装されていた点です。これは、現在のGoのスライスにおける append 関数の内部的な挙動と非常に似ています。

このファイルの削除は、Go言語のスライス機能が十分に成熟し、container/vector パッケージが提供していた機能が完全にスライスによって代替可能になったことを明確に示しています。これにより、Go言語の標準ライブラリはよりスリムになり、開発者はスライスという統一された強力なプリミティブを使用して動的配列を扱うことができるようになりました。

関連リンク

参考にした情報源リンク

  • Go言語のコミット履歴 (GitHub): https://github.com/golang/go/commits/master
  • Go言語の初期の議論に関する情報 (Go Mailing List archivesなど)
  • Go言語の設計に関するブログ記事やドキュメント
  • 一般的なプログラミングにおける動的配列の概念に関する情報