web-dev-qa-db-ja.com

Golangのシリアル化と逆シリアル化

構造体を文字列にシリアル化および逆シリアル化するためのGolangの最良の方法(完全性とパフォーマンス)は何ですか?

たとえば、この構造体がある場合:

struct Session {
   Properties map[string]interface{}
   Permissions []int64
}

Redis に保存して、取得し直します。私は、intとstringを保存しようとしましたが、大丈夫ですが、構造体オブジェクトを保存する方法は?

conn := redisConnectors.Get()

// set example

_, err := conn.Do(`SETEX`, `uid_key`, EXPIRE_SEC, user_id)
_, err = conn.Do(`SETEX`, `email_key`, EXPIRE_SEC, login_email)

// get example

user_id, err := redis.Int64(conn.Do(`GET`, `uid_key`))
login_email, err := redis.String(conn.Do(`GET`, `email_key`))
19
Kokizzu

gob および base64 を使用すると、次のように問題を解決できます。

import (
    "encoding/base64"
    "encoding/gob"
    "bytes"
)

type SX map[string]interface{}

// go binary encoder
func ToGOB64(m SX) string {
    b := bytes.Buffer{}
    e := gob.NewEncoder(&b)
    err := e.Encode(m)
    if err != nil { fmt.Println(`failed gob Encode`, err) }
    return base64.StdEncoding.EncodeToString(b.Bytes())
}

// go binary decoder
func FromGOB64(str string) SX {
    m := SX{}
    by, err := base64.StdEncoding.DecodeString(str)
    if err != nil { fmt.Println(`failed base64 Decode`, err); }
    b := bytes.Buffer{}
    b.Write(by)
    d := gob.NewDecoder(&b)
    err = d.Decode(&m)
    if err != nil { fmt.Println(`failed gob Decode`, err); }
    return m
}

カスタム構造体または型(たとえば、Session構造体)をシリアル化する必要がある場合は、次の行を追加します。

func init() {
    gob.Register(SX{})
    gob.Register(Session{}) 
}
25
Kokizzu

構造体のシリアル化では、通常 encoding パッケージを使用します。ただし、これはパブリックフィールドに対してのみ機能します。プライベートフィールドもシリアル化する必要がある場合は、代わりに この回答を参照 を使用してください。
いくつかのエンコードの選択肢があります(バイナリ、テキスト、 構造体のこの例のようなjson 、xmlなど)。たとえば、プロジェクト cupcake/rdb 使用 encoding/binaryRedisRDBファイル形式 (メモリ内ストアのバイナリ表現)の解析とエンコードを実装します。別の例は guregu/rediscache 、Redisでデータをキャッシュするための小さなライブラリ。

9
VonC