[インデックス 10889] ファイルの概要
コミット
コミットハッシュ:7bffdc724799c240ea796f3c7f5d1cbbb1e84d01
作成者:Andrew Gerrand adg@golang.org
日付:2011年12月20日 13:16:36 +1100
コミットメッセージ:encoding/binary: add Write and Read examples
GitHub上でのコミットページへのリンク
https://github.com/golang/go/commit/7bffdc724799c240ea796f3c7f5d1cbbb1e84d01
元コミット内容
このコミットでは、Goのencoding/binary
パッケージに対してサンプルコードを追加しました。新しいファイルsrc/pkg/encoding/binary/example_test.go
が作成され、以下の3つのサンプル関数が追加されています:
ExampleWrite()
- float64値(円周率)をバイナリ形式で書き込む例ExampleWrite_multi()
- 複数の異なる型の値をバイナリ形式で書き込む例ExampleRead()
- バイナリデータからfloat64値を読み込む例
変更の背景
2011年当時、GoはバージョンGo 1.0のリリースに向けて開発が進められていました。この時期、Goの標準ライブラリのドキュメント整備と、使いやすさの向上が重要な課題でした。encoding/binary
パッケージは、バイナリデータの読み書きという低レベルな操作を扱うため、具体的な使用例が開発者にとって非常に重要でした。
Andrew Gerrandは、Goチームの中でも特にドキュメント整備とコミュニティサポートを担当していたエンジニアで、この時期には多くのサンプルコードの追加やドキュメント改善を行っていました。2011年5月には"Real World Go"というプレゼンテーションを行い、Go言語の普及と教育に積極的に取り組んでいました。
前提知識の解説
encoding/binaryパッケージについて
encoding/binary
パッケージは、数値とバイト列の間の変換、およびvarint(可変長整数)のエンコード/デコードを実装するパッケージです。このパッケージは、固定サイズの値(bool、int8、uint8、int16、float32、complex64など)や、固定サイズの値のみを含む配列・構造体を扱います。
バイトオーダー(エンディアン)について
バイトオーダーは、マルチバイトデータのメモリ上での格納順序を指定するものです:
- BigEndian: 最上位バイトを先に格納する方式(ネットワークバイトオーダー)
- LittleEndian: 最下位バイトを先に格納する方式(x86系CPUで一般的)
Goのテストとサンプルコード
Goでは、_test.go
で終わるファイルにテストコードを記述します。特にExample
で始まる関数は、go test
コマンドでテストされるだけでなく、godoc
によってドキュメントのサンプルコードとして表示されます。
技術的詳細
追加されたサンプル関数の詳細
1. ExampleWrite()関数
func ExampleWrite() {
buf := new(bytes.Buffer)
var pi float64 = math.Pi
err := binary.Write(buf, binary.LittleEndian, pi)
if err != nil {
fmt.Println("binary.Write failed:", err)
}
fmt.Printf("% x", buf.Bytes())
}
この関数では、円周率(π)をfloat64
型で定義し、binary.Write
を使用してリトルエンディアン形式でバイナリデータとして書き込みます。出力は18 2d 44 54 fb 21 09 40
となります。
2. ExampleWrite_multi()関数
func ExampleWrite_multi() {
buf := new(bytes.Buffer)
var data = []interface{}{
int8(-54),
uint8(254),
uint16(48826),
}
for _, v := range data {
err := binary.Write(buf, binary.LittleEndian, v)
if err != nil {
fmt.Println("binary.Write failed:", err)
}
}
fmt.Printf("%x", buf.Bytes())
}
この関数では、異なる型の値(int8、uint8、uint16)を順次バイナリ形式で書き込みます。出力はcafebabe
となります。
3. ExampleRead()関数
func ExampleRead() {
var pi float64
b := []byte{0x18, 0x2d, 0x44, 0x54, 0xfb, 0x21, 0x09, 0x40}
buf := bytes.NewBuffer(b)
err := binary.Read(buf, binary.LittleEndian, &pi)
if err != nil {
fmt.Println("binary.Read failed:", err)
}
fmt.Print(pi)
}
この関数では、バイナリデータからfloat64値を読み込み、元の円周率の値(3.141592653589793)を復元します。
コアとなるコードの変更箇所
新しく追加されたsrc/pkg/encoding/binary/example_test.go
ファイルの全52行が、今回の変更の核心部分です。特に重要な箇所は以下の通りです:
- 行34-42:
ExampleWrite()
関数の実装 - 行45-59:
ExampleWrite_multi()
関数の実装 - 行62-71:
ExampleRead()
関数の実装
コアとなるコードの解説
binary.Write関数の使用例
binary.Write
関数は以下のシグネチャを持ちます:
func Write(w io.Writer, order ByteOrder, data interface{}) error
サンプルコードでは、bytes.Buffer
を書き込み先として使用し、binary.LittleEndian
をバイトオーダーとして指定しています。これにより、様々な型のデータを統一的にバイナリ形式で書き込むことができます。
binary.Read関数の使用例
binary.Read
関数は以下のシグネチャを持ちます:
func Read(r io.Reader, order ByteOrder, data interface{}) error
サンプルコードでは、事前に定義されたバイト配列からbytes.NewBuffer
を使用してReaderを作成し、指定されたバイトオーダーでデータを読み込みます。
エラーハンドリング
両方の関数とも、適切なエラーハンドリングを実装しており、バイナリ操作が失敗した場合にはエラーメッセージを出力するようになっています。これは、実際のアプリケーションでの使用時に重要な実装パターンです。
関連リンク
- encoding/binary パッケージ公式ドキュメント
- Go Walkthrough: encoding/binary
- Encoding Data with the Go Binary Package - Medium
- Go: A Documentary - golang.design