2015-01-19 15 views
14

Qual è il modo migliore (completezza e prestazioni) in Golang per serializzare e deserializzare una struttura in stringa e viceversa?Golang serializza e deserializza indietro

per esempio, se ho questo struct:

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

voglio memorizzare sul Redis a prendere indietro. Ho provato a salvare, int e string, va bene, ma come immagazzinare l'oggetto struct?

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`)) 
+1

Per riferimento, la libreria [boj/redistore] (https://github.com/boj/redistore/blob/master/redistore.go) serializza i dati della sessione su Redis usando 'encoding/gob' o' encoding/json' e salva la slice [] di byte non elaborata su Redis: https://github.com/boj/ redistore/blob/master/redistore.go # L313 – elithrar

risposta

16

Utilizzando gob e base64 potrebbe risolvere il problema, ad esempio:

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 
} 

e quando è necessario serializzare personalizzati struct o tipo (ad esempio Session struct), basta aggiungere queste righe:

func init() { 
    gob.Register(SX{}) 
    gob.Register(Session{}) 
} 
+5

Non dovresti nemmeno aver bisogno di codificare in base64 il risultato di gob - puoi semplicemente salvare il '[] byte' su Redis. Anche più veloce. Anche la codifica JSON è leggermente più veloce di 'encoding/gob', anche se è improbabile che sia una differenza sostanziale/evidente nella maggior parte delle app. – elithrar

+0

Ho già provato la codifica JSON, è il motivo per cui ho posto questa domanda, ma non è riuscito a convertire 'map [int] ..' o decodificare correttamente, ad esempio: 'map [string] bool' quando codificato e decodificato indietro sarebbe diventa 'map [string] interface {}' – Kokizzu

+0

Per 'map [int] ...' è necessario soddisfare le interfacce 'json.Marshaller' e' json.Unmarshaller' come le chiavi JSON sono stringhe. Il tuo 'map [string] bool' avrebbe dovuto funzionare bene però. – elithrar

7

La serializzazione di una struttura generalmente utilizza lo encoding.
che lavorerà per settore pubblico solo, non campi privati ​​(per questo, see this answer in alternativa)

avete diverse codifica scelta (binario, di testo, json as in this example for a struct, XML, ...)

Per esempio , il progetto cupcake/rdb utilizza encoding/binary per implementare l'analisi e la codifica dello RedisRDB file format (una rappresentazione binaria dell'archivio in memoria).

Un altro esempio con guregu/rediscache, una piccola libreria per i dati di memorizzazione nella cache in Redis.

+0

Il commento su "solo campo pubblico" era importante. –

Problemi correlati