以 JSON 格式为例,对 Go 的 struct 进行序列化与反序列化

import (
    "encoding/json"
    "fmt"
)

type Person struct {
    Name string
    Age  int
}

func main() {

    // struct to json
    person := Person{
        Name: "Tom",
        Age:  10,
    }
    marshaled, err := json.Marshal(person)
    if err != nil {
        fmt.Printf("Error marsaling %s\n", err)
        return
    }
    s := string(marshaled)
    fmt.Printf("Type: %T, Value:%+v\n", s, s)
}

    // json to struct
    person = Person{}
    if err = json.Unmarshal([]byte(strJSON), &person); err != nil {
        fmt.Printf("Error unmarsaling %s\n", err)
        return
    }
    fmt.Printf("Type: %T, Value:%+v\n", person, person)
}

也可以对 map 类型进行序列化与反序列化

func mapToJson(m map[string]interface{}) ([]byte, error) {
    marshaled, err := json.Marshal(m)
    if err != nil {
        fmt.Println("json encode failed, err:", err)
    }

    return marshaled, nil
}

func jsonToMap(b []byte) (map[string]interface{}, error) {
    var m map[string]interface{}
    err := json.Unmarshal(b, &m)
    if err != nil {
        fmt.Println("json decode failed, err:", err)
        return nil, err
    }
    return m, nil
}

但是 encoding/json 对于 map[string]interface 中的数字类型(整型、浮点型等)都序列化成 float64 类型。

可以使用 go 中自带另一种编码 gob 进行序列化或反序列化,可以保留原始数据格式

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

func mapToGob(m map[string]interface{}) ([]byte, error) {
    buf := new(bytes.Buffer)
    enc := gob.NewEncoder(buf)
    err := enc.Encode(m)
    if err != nil {
        fmt.Println("gob encode failed, err:", err)
        return nil, err
    }

    return buf.Bytes(), nil
}

func gobToMap(b []byte) (map[string]interface{}, error) {
    buf := bytes.NewBuffer(b)
    dec := gob.NewDecoder(buf)
    var m map[string]interface{}
    err := dec.Decode(&m)
    if err != nil {
        fmt.Println("gob decode failed, err:", err)
        return nil, err
    }
    return m, nil
}