为了账号安全,请及时绑定邮箱和手机立即绑定

如何在不反射的情况下将结构转储到字节数组中?

如何在不反射的情况下将结构转储到字节数组中?

Go
紫衣仙女 2021-04-27 22:45:59
我已经找到了编码/二进制包来处理它,但是它依赖于反射包,因此它不适用于未大写(即未导出)的结构字段。但是我花了一周的时间才发现这个问题,但我仍然有一个问题:如果不应该导出结构字段,如何将它们轻松转储为二进制数据?编辑:这是示例。如果将大写的Datastruct字段大写,则可以正常工作。但是Datastruct原本是一种抽象类型,所以我不想导出这些字段。package mainimport (    "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 回答

?
哔哔one

TA贡献1854条经验 获得超8个赞

最好的选择可能是使用gob包,并让您的结构实现GobDecoder和GobEncoder接口,以便对私有字段进行序列化和反序列化。


这将是安全,独立于平台且高效的。而且,您必须仅在具有未导出字段的结构上添加这些GobEncode和GobDecode函数,这意味着您不会使其余代码杂乱无章。


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)

}


查看完整回答
反对 回复 2021-05-17
  • 1 回答
  • 0 关注
  • 133 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信