How do I dump the struct into the byte array without reflection?

一个人想着一个人 提交于 2019-12-29 03:27:28

问题


I already found encoding/binary package to deal with it, but it depended on reflect package so it didn't work with uncapitalized(that is, unexported) struct fields. However I spent a week to find that problem out, I still have a question: if struct fields should not be exported, how do I dump them easily into binary data?

EDIT: Here's the example. If you capitalize the name of fields of Data struct, that works properly. But Data struct was intended to be an abstract type, so I don't want to export these fields.

package main
import (
    "fmt"
    "encoding/binary"
    "bytes"
)

type Data struct {
    id int32
    name [16]byte
}


func main() {
    d := Data{Id: 1}
    copy(d.Name[:], []byte("tree"))
    buffer := new(bytes.Buffer)
    binary.Write(buffer, binary.LittleEndian, d)
    // d was written properly
    fmt.Println(buffer.Bytes())
    // try to read...
    buffer = bytes.NewBuffer(buffer.Bytes())
    var e = new(Data)
    err := binary.Read(buffer, binary.LittleEndian, e)
    fmt.Println(e, err)
}

回答1:


Your best option would probably be to use the gob package and let your struct implement the GobDecoder and GobEncoder interfaces in order to serialize and deserialize private fields.

This would be safe, platform independent, and efficient. And you have to add those GobEncode and GobDecode functions only on structs with unexported fields, which means you don't clutter the rest of your code.

func (d *Data) GobEncode() ([]byte, error) {
    w := new(bytes.Buffer)
    encoder := gob.NewEncoder(w)
    err := encoder.Encode(d.id)
    if err!=nil {
        return nil, err
    }
    err = encoder.Encode(d.name)
    if err!=nil {
        return nil, err
    }
    return w.Bytes(), nil
}

func (d *Data) GobDecode(buf []byte) error {
    r := bytes.NewBuffer(buf)
    decoder := gob.NewDecoder(r)
    err := decoder.Decode(&d.id)
    if err!=nil {
        return err
    }
    return decoder.Decode(&d.name)
}

func main() {
    d := Data{id: 7}
    copy(d.name[:], []byte("tree"))
    buffer := new(bytes.Buffer)
    // writing
    enc := gob.NewEncoder(buffer)
    err := enc.Encode(d)
    if err != nil {
        log.Fatal("encode error:", err)
    }
    // reading
    buffer = bytes.NewBuffer(buffer.Bytes())
    e := new(Data)
    dec := gob.NewDecoder(buffer)
    err = dec.Decode(e)
    fmt.Println(e, err)
}


来源:https://stackoverflow.com/questions/12854125/how-do-i-dump-the-struct-into-the-byte-array-without-reflection

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!