[インデックス 14200] ファイルの概要
このコミットは、Go言語の標準ライブラリos
パッケージ内のドキュメントにおける誤字(typo)を修正するものです。具体的には、「array」と記述されていた箇所を、Go言語の慣用的なデータ構造である「slice」に修正しています。影響を受けるファイルはsrc/pkg/os/doc.go
とsrc/pkg/os/file.go
の2つです。
コミット
- コミットハッシュ:
eb7d56965b0373f52eb0f4ac42f2973a329dc5a4
- Author: Nigel Tao nigeltao@golang.org
- Date: Mon Oct 22 16:26:47 2012 +1100
GitHub上でのコミットページへのリンク
https://github.com/golang/go/commit/eb7d56965b0373f52eb0f4ac42f2973a329dc5a4
元コミット内容
os: fix documentation typos: s/an array/a slice/.
R=dsymonds
CC=golang-dev
https://golang.org/cl/6736057
変更の背景
このコミットの背景は、Go言語のos
パッケージのドキュメントにおける用語の正確性を向上させることです。Go言語では、固定長で値型である「配列(array)」と、可変長で参照型である「スライス(slice)」という、似て非なる2つのデータ構造が存在します。多くのGoのAPIは、柔軟性や効率性の観点から、配列ではなくスライスを返したり、引数として受け取ったりします。
os
パッケージのReaddir
関数はディレクトリの内容を読み込み、FileInfo
のリストを返しますが、これは実際にはスライスです。また、WriteString
関数は文字列をバイト列として書き込みますが、Goの文字列は内部的にはバイトのスライスとして扱われます。これらの関数のドキュメントで「array」と記述されているのは誤りであり、Go言語の設計思想や慣用的な使い方に合致させるために「slice」に修正する必要がありました。これは機能的な変更ではなく、ドキュメントの正確性を高めるための修正です。
前提知識の解説
Go言語における「配列(Array)」と「スライス(Slice)」は、どちらも要素のシーケンスを格納するために使用されますが、その性質と使用方法には根本的な違いがあります。
配列 (Array)
- 固定長: 配列は宣言時にサイズが固定され、一度宣言されるとそのサイズは変更できません。
- 値型: 配列は値型です。配列が別の配列変数に代入されたり、関数に渡されたりすると、配列全体のコピーが作成されます。
- サイズが型の一部: 配列のサイズは型の一部です。例えば、
[5]int
と[10]int
は異なる型と見なされます。 - 宣言例:
var a [5]int // 5つの整数を持つ配列を宣言(ゼロ値で初期化) b := [3]string{"apple", "banana", "cherry"} // 3つの文字列を持つ配列を宣言し初期化
- 用途: コンパイル時に正確な要素数が分かっており、その数が変更されない場合に主に使用されます。低レベルのデータ構造やC言語との相互運用などで見られますが、一般的なGoプログラミングではスライスに比べて使用頻度は低いです。
スライス (Slice)
- 動的サイズ: スライスは動的で柔軟性があります。必要に応じてサイズを拡大・縮小できます。スライスは配列の上に構築されています。
- 参照型: スライスは参照型です。データ自体を格納するのではなく、基になる配列の連続したセグメントを記述します。スライスが別のスライス変数に代入されたり、関数に渡されたりすると、両方のスライスが同じ基になる配列を参照します。
- 構造: スライスは以下の3つのコンポーネントを持つデータ構造です。
- ポインタ: スライスが参照する基になる配列の最初の要素を指します。
- 長さ (Length): スライスに含まれる現在の要素数です。
- 容量 (Capacity): スライスの最初の要素から始まる基になる配列の要素数で、基になる配列を再割り当てすることなくスライスが拡張できる最大数です。
- 宣言例:
var s []int // nilスライスを宣言 t := []string{"red", "green", "blue"} // スライスを宣言し初期化 u := make([]float64, 5, 10) // 長さ5、容量10のfloat64のスライスを作成
- 操作:
append
(要素を追加、容量を超えると新しい基になる配列が作成される可能性がある)や、既存のスライスから新しいスライスを作成するスライス操作をサポートします。 - 用途: 要素のコレクションが必要なほとんどのシナリオでスライスが使用されます。その動的な性質と柔軟性により、Goでのデータ操作のほとんどのタスクで推奨される選択肢であり、より強力でGoらしい方法です。
まとめ
特徴 | 配列 (Array) | スライス (Slice) |
---|---|---|
サイズ | 宣言時に固定 | 動的、拡大・縮小が可能 |
型 | 値型(代入時にコピー) | 参照型(基になる配列を共有) |
型定義 | サイズが型の一部 ([5]int ) | サイズは型の一部ではない ([]int ) |
一般的な使用 | 一般的な用途ではあまり使われない | コレクションとしてより一般的で柔軟 |
基盤 | 自己完結型 | 基になる配列の上に構築される |
このコミットは、Go言語のAPIが「配列」ではなく「スライス」を扱うことが一般的であるという事実をドキュメントに反映させるためのものです。
技術的詳細
このコミットは、Go言語のos
パッケージ内の2つのドキュメントコメントを修正しています。
-
src/pkg/os/doc.go
内のReaddir
関数の説明:Readdir
関数は、ディレクトリの内容を読み込み、FileInfo
のリストを返します。元のドキュメントでは「returns an array of up to n FileInfo values」と記述されていましたが、Go言語のReaddir
関数は実際には[]FileInfo
、つまりFileInfo
のスライスを返します。スライスは動的なサイズ変更が可能であり、Go言語でコレクションを扱う際の標準的な方法です。配列は固定長であるため、ディレクトリ内のファイル数が事前に不明な場合に配列を返すのは不適切です。 -
src/pkg/os/file.go
内のWriteString
関数の説明:WriteString
関数は、文字列をファイルに書き込みます。元のドキュメントでは「writes the contents of string s rather than an array of bytes」と記述されていましたが、Go言語において文字列は内部的にUTF-8エンコードされたバイトのスライスとして扱われます。したがって、文字列のコンテンツをバイトの「配列」としてではなく、「スライス」として扱うという表現がより正確です。
これらの修正は、Go言語のデータ構造に関する正確な用語を使用することで、ドキュメントの理解を深め、GoプログラマーがAPIの挙動を正しく把握できるようにすることを目的としています。これは、Go言語の設計哲学である「シンプルさ」と「明確さ」にも合致する変更です。
コアとなるコードの変更箇所
--- a/src/pkg/os/doc.go
+++ b/src/pkg/os/doc.go
@@ -89,7 +89,7 @@ func Hostname() (name string, err error) {
}
// Readdir reads the contents of the directory associated with file and
-// returns an array of up to n FileInfo values, as would be returned
+// returns a slice of up to n FileInfo values, as would be returned
// by Lstat, in directory order. Subsequent calls on the same file will yield
// further FileInfos.
//
--- a/src/pkg/os/file.go
+++ b/src/pkg/os/file.go
@@ -185,7 +185,7 @@ func (f *File) Seek(offset int64, whence int) (ret int64, err error) {
}
// WriteString is like Write, but writes the contents of string s rather than
-// an array of bytes.
+// a slice of bytes.
func (f *File) WriteString(s string) (ret int, err error) {
if f == nil {
return 0, ErrInvalid
コアとなるコードの解説
src/pkg/os/doc.go
の変更
Readdir
関数のドキュメントコメントが修正されています。
- 変更前:
// returns an array of up to n FileInfo values, as would be returned
- 変更後:
// returns a slice of up to n FileInfo values, as would be returned
Readdir
関数は、os.FileInfo
型のスライスを返します。FileInfo
はファイルやディレクトリのメタデータ(名前、サイズ、パーミッションなど)を保持するインターフェースです。ディレクトリの内容は動的に変化する可能性があり、またその要素数も事前に確定できないため、固定長の配列ではなく、動的にサイズを変更できるスライスが適切な戻り値となります。この修正は、実際の関数の挙動とドキュメントの記述を一致させるものです。
src/pkg/os/file.go
の変更
WriteString
関数のドキュメントコメントが修正されています。
- 変更前:
// WriteString is like Write, but writes the contents of string s rather than // an array of bytes.
- 変更後:
// WriteString is like Write, but writes the contents of string s rather than // a slice of bytes.
Go言語において、文字列(string
型)は不変のバイトスライスとして内部的に表現されます。WriteString
関数は、与えられた文字列のバイト表現をファイルに書き込みます。この文脈で「バイトの配列」という表現は不正確であり、「バイトのスライス」が正しい表現です。この修正も、Go言語の型システムと文字列の内部表現に関する正確な情報を提供するものです。
これらの変更は、Go言語のドキュメントの品質と正確性を向上させるための、細かではあるが重要な修正です。
関連リンク
- Go CL 6736057: https://golang.org/cl/6736057
参考にした情報源リンク
- Go Slices: usage and internals: https://go.dev/blog/slices-intro
- Go Arrays vs Slices (Web Search): https://www.google.com/search?q=Go+slices+vs+arrays