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

[インデックス 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つのサンプル関数が追加されています:

  1. ExampleWrite() - float64値(円周率)をバイナリ形式で書き込む例
  2. ExampleWrite_multi() - 複数の異なる型の値をバイナリ形式で書き込む例
  3. 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を作成し、指定されたバイトオーダーでデータを読み込みます。

エラーハンドリング

両方の関数とも、適切なエラーハンドリングを実装しており、バイナリ操作が失敗した場合にはエラーメッセージを出力するようになっています。これは、実際のアプリケーションでの使用時に重要な実装パターンです。

関連リンク

参考にした情報源リンク