猿问

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

我已经找到了编码/二进制包来处理它,但是它依赖于反射包,因此它不适用于未大写(即未导出)的结构字段。但是我花了一周的时间才发现这个问题,但我仍然有一个问题:如果不应该导出结构字段,如何将它们轻松转储为二进制数据?


编辑:这是示例。如果将大写的Datastruct字段大写,则可以正常工作。但是Datastruct原本是一种抽象类型,所以我不想导出这些字段。


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)

}


紫衣仙女
浏览 134回答 1
1回答

哔哔one

最好的选择可能是使用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)}
随时随地看视频慕课网APP

相关分类

Go
我要回答