はじめに
やりたいこと
Goのプログラム内で作成した構造体のデータをバイナリにシリアライズし、ファイルに保存します。
そしてプログラムを次回実行したときには、そのファイルを読み込んでデシリアライズし、構造体のデータをメモリに乗せます。
丁度、Pythonであればpickleで出来るようなことを、Goで実行する方法のメモです。
コード
概要
Goの標準ライブラリであるgobを用います。
Encoder
というクラスで構造体データをバイナリにシリアライズし、Decoder
というクラスでそれをデシリアライズします。
※サンプルコードからは、例外処理を省いています。
書き込み
import (
"encoding/gob"
)
// 今回保存したいデータ
var stageTiles [screenLength][screenLength]tileInfo
type tileInfo struct {
SpritesheetNum int
TileType string
}
// 中略
// セーブファイルの作成
file, _ := os.Create("savefile.gob")
defer file.Close()
// エンコーダーの作成
encoder := gob.NewEncoder(file)
// エンコード
encoder.Encode(stageTiles)
注意したいのが、シリアライズする構造体のフィールドです。構造体のフィールドが他のパッケージからアクセスできるようになっていないと(i.e. 先頭が大文字になっていないと)、値はシリアライズされるデータに含まれません。
Structs encode and decode only exported fields.
上のコードの場合、tileInfo
というtypeの二重配列をファイルに保存していますが、最初私はこのtypeのフィールド名を小文字にしていたため、読み込み時に値が初期値(intなら0, stringなら空文字)となっていて、困惑しました。
読み込み
import (
"encoding/gob"
)
// 読み込んだデータを保持する変数
var stageTiles [screenLength][screenLength]tileInfo
type tileInfo struct {
SpritesheetNum int
TileType string
}
// 中略
file, _ := os.Open("savefile.gob")
defer file.Close()
decoder := gob.NewDecoder(file)
err = decoder.Decode(&stageTiles)