Go言語では、データ構造のシリアライズにはGobエンコーディングが利用されます。また、分散システム間通信にはRPC(Remote Procedure Call)が使用されます。
Gobエンコーディングの基本 GobはGo標準ライブラリのencoding/gobパッケージで提供されるバイナリシリアライゼーション形式です。データ構造のエンコードにはEncoder、デコードにはDecoderを使用します。
package main
import (
"bytes"
"encoding/gob"
"fmt"
)
type DataPair struct {
X, Y, Z int
Label string
}
type DecodedPair struct {
X, Y *int32
Label string
}
func main() {
original := DataPair{10, 20, 30, "Example"}
buffer := serialize(original)
result := deserialize(buffer)
fmt.Printf("%s: {%d,%d}\n", result.Label, *result.X, *result.Y)
}
func serialize(data interface{}) *bytes.Buffer {
var buffer bytes.Buffer
encoder := gob.NewEncoder(&buffer)
encoder.Encode(data)
return &buffer
}
func deserialize(data interface{}) *DecodedPair {
reader := data.(*bytes.Buffer)
decoder := gob.NewDecoder(reader)
var q DecodedPair
decoder.Decode(&q)
return &q
}
ファイル操作におけるGobの活用 データ構造の永続化にはファイルへのシリアライズが有用です。
package main
import (
"encoding/gob"
"fmt"
"os"
)
type Location struct {
City string
Country string
}
const storagePath = "./location.dat"
func main() {
saveData()
restored := loadData()
fmt.Println(*restored)
}
func saveData() {
loc := &Location{"Tokyo", "Japan"}
file, _ := os.Create(storagePath)
defer file.Close()
encoder := gob.NewEncoder(file)
encoder.Encode(loc)
}
func loadData() *Location {
file, _ := os.Open(storagePath)
defer file.Close()
var loc Location
decoder := gob.NewDecoder(file)
decoder.Decode(&loc)
return &loc
}
RPCの基本実装 Goのnet/rpcパッケージを使用した簡単なRPC実装例を示します。
サーバー実装
package main
import (
"net"
"net/http"
"net/rpc"
)
type Operands struct {
A, B int
}
type Calculator int
func (c *Calculator) Multiply(args *Operands, result *int) error {
*result = args.A * args.B
return nil
}
func main() {
calc := new(Calculator)
rpc.Register(calc)
rpc.HandleHTTP()
listener, _ := net.Listen("tcp", ":8080")
http.Serve(listener, nil)
}
クライアント実装
package main
import (
"fmt"
"net/rpc"
)
type Operands struct {
A, B int
}
func main() {
client, _ := rpc.DialHTTP("tcp", "localhost:8080")
params := &Operands{15, 20}
var response int
client.Call("Calculator.Multiply", params, &response)
fmt.Printf("Result: %d*%d=%d\n", params.A, params.B, response)
}
RPCメソッドの設計要件
公開メソッド(大文字開始)であること 引数と戻り値の型がエクスポート可能であること 戻り値パラメータはポインタ型であること error型の戻り値を持つこと パラメータ型がGobエンコード可能であること